Parallélisme : travaux dirigés et pratiques

1. Introduction Générale

Science sans conscience n'est que ruine de l'âme, Rabelais

1.1. Introduction

Depuis 2005 avec l'arrivée des Pentium D (Smithfield = 2 Pentium 4 Prescott), les processeurs d'architecture x86 disposent dans leur grande majorité de plusieurs coeurs de calcul. Cela permet de rendre l'expérience utilisateur beaucoup plus agréable. Par exemple un coeur peu s'occuper de l'interface graphique, un autre de la base de données, le troisième du seveur web, etc.

Un autre intérêt est l'exécution d'un même code sur plusieurs coeurs pour des données différentes. On diminue ainsi le temps de calcul en répartissant la charge de travail sur plusieurs dispositifs matériels.

On parle alors de programmation parallèle ou concurrentielle. Le terme concurrentiel est plutôt utiliser avec des programmes parallèles qui doivent avoir accès aux mêmes ressources et sont donc en concurrence pour avoir accès à ces ressources.

La programation parallèle et les architectures parallèles ne sont pourtant pas récentes car on peut les faire remonter aux années 50, mais programmer en parallèle est souvent vu comme une tâche difficile :

Tout ceci tend à décourager le néophyte, pourtant, de nos jours des solutions simples à mettre en oeuvre existent, comme OpenMP qui permet dorénavant d'introduire du parallélisme dans un programme séquentiel en ajoutant une directive #pragma avant une boucle for par exemple.

1.2. CPU, GPU et parallélisme

1.2.1. Cas des GPU

Si les microprocesseurs CPU sont des dispositifs généraux de calcul, cela est quelque peu différent pour les cartes graphiques GPU, qui sont très fortement axés sur le traitement parallèle.

Pour les calculs en virgule flottante les cartes graphiques apparaissent comme des monstres de puissance de calcul comparativement aux processeurs. L'introduction de la technologie CUDA de NVidia permet, tout en gardant une syntaxe C++, de déporter une partie des calculs vers le GPU vu alors comme une sorte de coprocesseur.

Notons qu'en 2016 la GTX 1080 de NVidia possède une puissance de calcul en simple précision de 8873 GFlops pour un prix de 600 dollars, alors que le Cray T932 (32 processeurs) développé à la fin des années 90 avait une puissance de 60 GFlops pour un cout de 35 millions de dollars, un poids de 4545 kg et des dimensions de 2.3 m x 1.5 m x 1.5 m.

 Caractéristique   Cray T932   GTX 1080   Evolution 
 année   1997   2016   +20 ans 
 puissance GFlops   60   8873   x 147.88 
 prix (dollars)   35.000.000   600   / 58_333 
 rapport performance/cout   0.0000017   14.79   x 8_700_000 
Comparaison puissance de calcul / cout

1.2.2. Cas des CPU

Ces dernières années on a assisté, grâce au fait que AMD soit revenu au premier plan, à une augmentation du nombre de coeurs par processeur.

Par exempl, 2017 voit l'arrivée des microprocesseurs :

  • AMD Ryzen séries 1700 et 1800 avec 8 coeurs et 16 Threads pour un prix inférieur à \$500.
  • Ryzen Threadripper* 1950X : 16C/32T \$999 (août 2017)
  • De même chez Intel avec les Skylake-X 980XE 18C/36T à \$2000.

(*) ripper signifie défonceuse (pour les Bulldozers).

En 2020, l'AMD Threadripper 3990X comporte 64 coeurs et 128 threads.

En 2021, Intel lance les premiers processeurs hybrides de la gamme Alder Lake comme le Core i9 12900K doté de 8 coeurs Performance (soit 16 threads) et 8 coeurs Efficiency (8 threads), soit un total de 24 threads.

1.3. Qu'est ce que le parallélisme et à quoi sert-il ?

Définition: Parallélisme

capacité à exécuter du code de manière simultanée sur différents dispositifs matériels (CPU, GPU APU,...).

On distingue généralement :

  • le parallélisme de données : le même programme s'exécute sur des données différentes
  • le parallélisme de tâches : des programmes différents traitent sur les mêmes données, ou des données différentes

Le parallélisme vise à diminuer le temps de calcul d'un programe en répartissant la charge de travail sur $N$ dispositifs matériels plutôt qu'un seul.

On fonctionne généralement par décomposition du problème initial en sous-problèmes qui peuvent être résolus indépendamment les uns des autres.

D'autres aspects sont également à prendre en considération :

1.4. Classification/Taxonomie de Flynn

Bien que cette classification soit ancienne (1966) elle permet de donner un aperçu des modes de fonctionnement envisageables pour le parallélisme. Le mot single n'est pas à prendre au sens d'unique mais signifie pour les données ne sont pas démultipliées :

Flynn Taxonomy

SISD (Single Instruction, Single Data)
Correspond à un CPU doté d'un coeur où une instruction travaille sur une donnée à la fois. Il s'agit du modèle classique d'exécution dit de Von Neumann.
SIMD (Single Instruction, Multiple Data)
Cas des processeurs vectoriels ou unités vectorielles (SSE, AVX : paddd, addps)
MISD (Multiple Instructions, Single Data)
Peu répandu car pas naturel, voire inexistant. Eventuellement on peut penser aux FPGA (Field-programmable Gate Array) pour ce genre de fonctionement
MIMD (Multiple Instructions, Multiple Data)
Cas des processeurs multi-coeurs avec des processus différents qui travaillent sur des données différentes. Cas des clusters de machines

Notons que bien que nos processeurs actuels puissent être dotés d'un seul coeur, ils exploitent néanmoins le parallélisme au niveau des instructions : ILP (Instruction Level Parallelism). Par exemple une instruction sur les entiers (ALU) peut être exécutée en parallèle d'une instruction sur les flottants (FPU).

1.5. Les différents niveaux de parallélisme

Flynn Taxonomy
Document Intel de Michael Klemm, Senior Application Engineer

1.6. MIMD et Partage de la mémoire

Dans le cas des systèmes MIMD, on distingue plusieurs architectures pour l'accès à la mémoire :

En fait on devrait plutôt de système :

  • à mémoire globale (au lieu de partagé)
  • à mémoire répartie (au lieu de distribuée)

Flynn Taxonomy as Tree

Note : COW signifie Cluster Of Workstations.

1.6.1. Mémoire partagée - ou globale

Un multiprocesseur symétrique (à mémoire partagée), ou symmetric shared memory multiprocessor (SMP) est une architecture parallèle qui consiste à utiliser des processeurs identiques au sein d'un ordinateur de manière à augmenter la puissance de calcul tout en conservant une mémoire unique.

dans ce cas on peut distinguer les organisations :

1.6.1.a  Exemple

Cas du cluster taurus du LERIA qui dispose de Racks Bull Novascale R422 composés de deux Xeon E5 2670 v2

Bull Novascale 422

1.6.2. Mémoire distribuée

Pour connecter les processeurs et leurs mémoires on crée un réseau d'interconexions qui peut prendre plusieurs formes : carré, grille à deux dimensions, arbre, hypercube, ...

On parle également de Message-Passing MIMD Architecture

1.7. Problèmes rencontrés

Ce sont les mêmes que lors des accès concurentiels.

1.8. Solutions de parallélisation

Voici une liste non exhaustive des solutions de parallélisation :

Sur un seul processeur ou un SMP (systèmes à mémoire partagée)
  • bas niveau :
    • pThread (où POSIX threads) voir le tutoriel du Lawrence Livermore National Laboratory (LLNL)
    • les threads (C++11) : classe reposant sur les POSIX threads
    • calcul sur carte graphique : technologie CUDA de NVidia
    • calcul sur super-processeur Intel Xeon Phi
  • haut niveau :
    • Intel Threading Building Blocks (TBB) : bibliothèque C++ qui utilise les templates
    • OpenMP : directives de compilation et vectorisation
    • la librairie thrust pour les cartes graphiques
Entre plusieurs processeurs sur différentes machines (systèmes à mémoire distribuée)
  • PVM : est un ensemble de bibliothèques logicielles et outils libres de comunication (langages C et Fortran) pour machines parallèles et réseaux d'ordinateurs (locaux ou distants, éventuellement hétérogènes). Il permet d’agréger un réseau d'ordinateurs en un seul ordinateur virtuel permetant ainsi d'augmenter la concurence des calculs. PVM a été graduellement remplacé par MPI.
  • MPI (Message Passing Interface) : communication entre machines grâce à l'envoi de messages pour échanger de l'information. Notons que MPI fonctione également sur les systèmes à mémoire distribuée.

Autres solutions similaires à OpenMP:

Enfin, il existe des solutions de très haut niveau comme StarPU (INRIA) qui se définit comme : a runtime system that offers support for heterogeneous multicore architectures.

1.9. Super calculateurs et High Performance Computing

Un autre aspect de la parallélisation est le HPC (où High Performance Computing) très en vogue depuis quelques années et qui consiste à concevoir et utiliser de manière efficace un ensemble de machines/processeurs afin de réduire le temps d'exécution d'un calcul complexe.

Le calcul haute performance a pour objectif d'atteindre les plus hautes performances possibles en terme de calcul avec des technologies de pointe. Les machines qui résultent de la conception basée sur ce principe sont qualifié de superordinateurs ou supercalculateurs (super computers). L'activité scientifique chargée de concevoir et programmer ces superordinateurs est appelée Calcul Haute Performance ou HPC en anglais pour High Performance Computing.

La puissance des supercalculateurs est exprimé en Flops (Floating Point Operations per Second) car la plupart des applications susnommées utilisent les nombres rééls pour représenter des coordonnées dans l'espace, des distances, des forces, des énergies, ... On utilise le test LINPACK (Résolution de systèmes d'équations linéaires) pour évaluer la puissance des supercalculateurs.

Diférentes barières ont été ateintes au cours du temps :

On parle également à présent de l'Exascale Computing pour le passage à l'ExaFlop ($10^18$ Flops) prévu (initialement pour 2020) pour 2022 pour la plupart des grandes puissances (Europe, Chine, Japon, USA, Inde).

Les organismes de recherche civils et militaires comptent parmi les utilisateurs de superordinateurs qui sont destinés aux principaux domaines suivants :

Le site top500.org recense les superordinateurs les plus puissants.

On peut également comparer le rapport puissance / nombre de coeurs. Notamment dans la table suivante la colonne estimation correspond à la puissance en PFlops si on utilisait le nombre de coeurs du SunWay TaihuLight.

 Système   Rang   Puissance
(GFlops) 
 Coeurs   Ratio (P/C)   Estimation
(PFlops) 
 Sunway TaihuLight   1   93.014.600   10.649.600   8.73   93 
 Tianhe-2   2   33.862.700   3.120.000   10.85   37 
 Titan   3   17.590.000   560.640   31.37   595 
Comparaison Puissance de calcul - Nombre de coeurs (Juin 2016)

Le site green500.org recense quant à lui les superordinateurs consommant le moins d'énergie.

1.9.0.a  quelques exemples de supercalculateurs

Voici quelques extraits du dossier complet publié sur Tomshardware.com concernant le sujet :