Séance 1 — Fondements de l’architecture parallèle

Fondements de l’architecture parallèle

Dr. El Hadji Bassirou TOURÉ

Département de Mathématiques et Informatique, Faculté des Sciences et Techniques, Université Cheikh Anta Diop de Dakar

Objectifs de la séance

Ce que la séance construit

Les processeurs ne gagnent plus en fréquence depuis le milieu des années 2000 : ils gagnent des cœurs. Un programme ne va donc plus plus vite tout seul ; il doit répartir son travail. La séance pose les fondements du cours : pourquoi le parallélisme s’est imposé, comment classer les machines, comment la mémoire est organisée, comment mesurer le gain et ce qui le limite.

  • Expliquer l’arrêt de la montée en fréquence par \(P=C\,V^2f\), et ce que plusieurs cœurs apportent.
  • Classer une architecture selon Flynn : SISD, SIMD, MISD, MIMD.
  • Situer registres, caches et mémoire principale en cycles ; suivre une ligne de cache, un succès, un défaut.
  • Calculer l’accélération et l’efficacité d’un programme parallèle.
  • Appliquer les lois d’Amdahl et de Gustafson, et dire laquelle convient à un problème.
  • Choisir une granularité selon le surcoût et le nombre de processeurs.

La nécessité du parallélisme

Processeur, fréquence et cycle

Processeur, fréquence, cycle

Le processeur exécute les instructions. Sa fréquence d’horloge (en hertz) donne le nombre de cycles par seconde : un processeur à \(3\) GHz bat \(3\) milliards de cycles par seconde.

Un cycle d’horloge est un « battement » de l’horloge, l’unité de temps qui rythme toutes les opérations ; une instruction prend un ou plusieurs cycles selon sa complexité. À \(3\) GHz, un cycle dure \(1/3\) ns, soit environ \(0{,}33\) ns.

Pendant des décennies, le nombre de transistors par puce a doublé environ tous les deux ans (loi de Moore), et les performances ont suivi presque au même rythme. Le gain venait de trois sources :

  • la fréquence d’horloge (des MHz aux GHz) ;
  • la miniaturisation des transistors ;
  • une architecture séquentielle plus habile.

Un programme écrit une fois allait plus vite à chaque génération, sans être modifié. Ce n’est plus le cas depuis le milieu des années 2000.

Cinquante ans de processeurs

Lecture. Les transistors (gris) doublent environ tous les deux ans : loi de Moore. La fréquence (bleu) plafonne à quelques GHz à partir du milieu des années 2000 (Pentium 4 à \(3{,}8\) GHz, novembre 2004). Les cœurs (rouge), un seul jusque-là, se multiplient ensuite.

Le mur de la fréquence

Puissance dissipée

\[ P = C \times V^2 \times f \]

\(C\) : capacité commutée ; \(V\) : tension ; \(f\) : fréquence.

Vers 2004, une limite physique est atteinte :

  • fréquence maximale d’environ \(3\) à \(4\) GHz (Pentium 4 à \(3{,}8\) GHz, novembre 2004) ;
  • chaleur à évacuer et consommation électrique prohibitives ;
  • courants de fuite dans les transistors nanométriques.

La solution : plusieurs cœurs qui travaillent ensemble, au lieu d’un processeur très rapide.

Lecture. Si \(V\) suit \(f\) (hypothèse d’école), \(P\) varie comme \(f^3\) : à \(0{,}8\,f\), un cœur dissipe \(0{,}512\) fois la puissance ; deux cœurs à \(0{,}8\,f\) font \(1{,}6\) fois le travail pour \(1{,}024\) fois la puissance.

Paradigme séquentiel, paradigme parallèle

Lecture. Un seul processeur enchaîne les huit tâches : le travail se termine à \(8t\). Quatre processeurs identiques en prennent deux chacun et finissent ensemble à \(2t\) : accélération \(8t/2t=4\). Le gain suppose des tâches indépendantes ; une tâche qui attend le résultat d’une autre ne peut pas démarrer en même temps qu’elle.

Exercice : le gain théorique

Énoncé

Un processeur mono-cœur de 2004 fonctionne à \(3{,}6\) GHz. Un processeur moderne a \(8\) cœurs à \(2{,}4\) GHz chacun.

Question : quel est le gain théorique maximal de performance ?

Correction

  • Processeur 2004 : \(1 \times 3{,}6 = 3{,}6\) GHz de capacité de calcul.
  • Processeur moderne : \(8 \times 2{,}4 = 19{,}2\) GHz de capacité théorique.
  • Gain théorique maximal : \(19{,}2 / 3{,}6 = \mathbf{5{,}33}\).

Hypothèse : même nombre d’instructions par cycle dans les deux processeurs.

Note importante : ce gain n’est atteint que si le programme occupe parfaitement les \(8\) cœurs. En pratique, la partie séquentielle du code l’empêche (loi d’Amdahl). Un programme séquentiel, lui, va \(2{,}4/3{,}6 = 0{,}67\) fois aussi vite : il ralentit.

Taxonomie de Flynn

La taxonomie de Flynn (1966)

Lecture. Michael Flynn classe les architectures selon le nombre de flux d’instructions et de flux de données traités simultanément ({Single} ou {Multiple}). SIMD : un contrôle commande plusieurs unités de calcul ; MISD : plusieurs traitements sur une même donnée.

SISD et SIMD

SISD

({Single Instruction, Single Data}) Architecture séquentielle classique : une seule instruction est exécutée sur une seule donnée à la fois. C’est le modèle de von Neumann traditionnel.

Exemples : Intel 8086, ARM Cortex-M0, microcontrôleur d’une carte Arduino Uno. Usage : microcontrôleurs, systèmes embarqués.

SIMD

({Single Instruction, Multiple Data}) Une même instruction s’applique simultanément à plusieurs données (traitement vectoriel, tableaux).

Exemples : SSE/AVX (Intel), NEON (ARM), GPU (SIMT chez NVIDIA, une variante de SIMD). Usage : traitement d’images, calcul scientifique, apprentissage profond.

Lecture. Sur le schéma, quatre additions scalaires demandent quatre instructions ; une seule instruction vectorielle additionne les quatre paires d’un coup.

MISD et MIMD

MISD

({Multiple Instruction, Single Data}) Plusieurs instructions différentes traitent la même donnée. Très rare en pratique, surtout utilisé pour la redondance.

  • exemple : systèmes redondants pour la tolérance aux fautes ;
  • usage : systèmes critiques (spatial, nucléaire) ;
  • beaucoup d’auteurs rangent ces systèmes en MIMD.

MIMD

({Multiple Instruction, Multiple Data}) Plusieurs processeurs exécutent des instructions différentes sur des données différentes. C’est l’architecture la plus flexible et la plus courante aujourd’hui.

Exemples : processeurs multicœurs, grappes ({clusters}). Usage : serveurs, stations de travail, supercalculateurs.

Les classes se cumulent

Un multicœur est MIMD ; chacun de ses cœurs exécute aussi des instructions SIMD (AVX).

Exercice : classement selon Flynn

Énoncé

Classer les architectures suivantes selon Flynn :

  1. un GPU qui exécute la même opération sur \(1024\) pixels ;
  2. un processeur à quatre cœurs où chaque cœur exécute un programme différent ;
  3. le microcontrôleur d’une carte Arduino Uno ;
  4. un pipeline de vérification où \(3\) unités vérifient le même calcul.

Correction

  1. SIMD : une instruction (même opération) sur plusieurs données (\(1024\) pixels).
  2. MIMD : instructions multiples (programmes différents) sur données multiples.
  3. SISD : architecture séquentielle classique.
  4. MISD : instructions multiples (\(3\) vérifications) sur une même donnée.

Hiérarchies mémoire

La hiérarchie mémoire en cycles

Un cycle dure environ \(0{,}3\) ns à \(3\) GHz ; un accès à la mémoire principale prend \(60\) à \(100\) ns, environ \(200\) à \(300\) fois plus (\(180\) à \(300\) cycles). La hiérarchie mémoire range le stockage en niveaux ; chaque niveau sert de cache au niveau inférieur.

Lecture. Ordres de grandeur des processeurs de bureau des années 2020 (\(1\) ns \(=3\) cycles à \(3\) GHz). Exemple daté : AMD Zen 4 (2022), L2 de \(1\) Mio en \(14\) cycles, L3 de \(32\) Mio en \(50\) cycles.

Registres, SRAM, DRAM

Registres SRAM ({Static RAM}) DRAM ({Dynamic RAM})
technologie intégrés au processeur \(6\) transistors par bit \(1\) transistor et \(1\) condensateur par bit
temps d’accès moins d’un cycle (\(<0{,}3\) ns) \(1\) à \(2\) ns \(60\) à \(100\) ns
capacité quelques dizaines (\(32\) à \(64\)) quelques Mio \(8\) à \(32\) Gio
coût — de l’ordre de cent fois la DRAM par Gio quelques dollars le Gio
usage variables temporaires, pointeurs caches L1, L2, L3 mémoire principale (RAM)
particularité — pas de rafraîchissement rafraîchissement périodique (d’où « dynamique »)

Lecture. La SRAM est rapide mais encombrante sur le silicium : elle sert aux caches. La DRAM, dense et bon marché, sert à la mémoire principale. Le prix de la DRAM varie fortement d’une année à l’autre ; les coûts sont des ordres de grandeur.

Exercice : temps d’accès en cycles

Énoncé

Un processeur a les caractéristiques suivantes :

  • fréquence \(3\) GHz (cycle de \(1/3\) ns) ;
  • cache L1 : accès en \(1\) ns ;
  • mémoire principale : accès en \(100\) ns.
  1. Combien de cycles pour un accès L1 ?
  2. Combien de cycles pour un accès mémoire ?
  3. Quel ralentissement sans cache ?

Correction

  1. L1 : \(1~\text{ns} \times 3~\text{cycles/ns} = \mathbf{3}\) cycles.
  2. Mémoire : \(100~\text{ns} \times 3~\text{cycles/ns} = \mathbf{300}\) cycles.
  3. Ralentissement : \(300/3 = \mathbf{100}\) fois plus lent sans cache.

Conclusion : le cache est indispensable ; sans lui, le processeur passerait \(99\,\%\) de son temps à attendre la mémoire.

Piège d’arrondi : diviser par \(0{,}33\) donne \(303\) cycles et un rapport de \(101\) ; l’écart vient seulement de l’arrondi de \(1/3\).

Introduction aux caches

Les deux principes de localité

Le cache comble l’écart de la hiérarchie en exploitant deux propriétés des programmes.

Localité temporelle : une donnée lue maintenant sera probablement relue bientôt.

Localité spatiale : après une donnée, ses voisines en mémoire seront probablement lues.

Lecture. Le cache garde les données récemment utilisées (temporelle) et charge des blocs entiers de données voisines (spatiale).

Une ligne de cache, un bloc de mémoire

Lecture. La mémoire est une suite de blocs de \(64\) octets : le bloc \(k\) couvre les octets \(64k\) à \(64k+63\). Un tableau t d’entiers de \(4\) octets rangé à partir de l’adresse \(0\) met \(16\) entiers par bloc.

Lecture. t[50] est à l’adresse \(4\times50=200\) ; son bloc est \(\lfloor 200/64\rfloor=3\) (orange : examiné), qui couvre les octets \(192\) à \(255\), soit t[48] à t[63].

Lecture. Un défaut sur t[50] charge le bloc entier : ses \(64\) octets sont copiés dans une ligne du cache (rouge : modifiée), avec t[48] à t[63] ; les \(15\) voisins sont désormais en cache.

Succès et défaut de cache

Le cache est organisé en lignes de cache (ou blocs) :

  • taille typique : \(64\) octets (\(16\) entiers de \(32\) bits) ;
  • unité de transfert entre cache et mémoire ;
  • c’est ainsi que le cache exploite la localité spatiale.

Succès et défaut de cache

Un succès ({cache hit}) : la donnée demandée est dans le cache. Un défaut ({cache miss}) : elle n’y est pas et doit être chargée depuis la mémoire.

Quand le processeur demande une donnée :

  1. le gestionnaire de cache vérifie si elle est présente ;
  2. succès : accès rapide (quelques cycles, \(3\) à \(6\) en L1) ;
  3. défaut :

    • la ligne complète est chargée depuis la mémoire ;
    • l’attente dépasse \(100\) cycles (pénalité de défaut) ;
    • une ligne existante est éventuellement évincée.

Une demande au cache, pas à pas

Lecture. Le processeur demande t[50], à l’adresse \(200\), donc dans le bloc \(3\). Le cache L1 est examiné (orange) : ses quatre lignes contiennent les blocs \(9\), \(12\), \(1\) et \(6\).

Lecture. Le bloc \(3\) n’est dans aucune ligne : c’est un défaut. La demande passe à la mémoire principale.

Lecture. La mémoire envoie le bloc \(3\) entier, \(64\) octets, en environ \(300\) cycles (\(100\) ns à \(3\) GHz). Il remplace la ligne la moins récemment utilisée, celle du bloc \(1\), qui est évincée (rouge : ligne modifiée).

Lecture. La donnée t[50] est lue dans la ligne (orange) et transmise au processeur. Le défaut a coûté environ \(300\) cycles ; pendant ce temps, le processeur attendait.

Lecture. Demande suivante : t[51], adresse \(204\), encore dans le bloc \(3\), maintenant présent dans L1 : succès, en environ \(3\) cycles (\(1\) ns), cent fois moins qu’un défaut.

Exercice : cent entiers parcourus

Énoncé

Un programme lit dans l’ordre un tableau de \(100\) entiers de \(4\) octets.

  • ligne de cache : \(64\) octets ;
  • succès : \(1\) ns ;
  • défaut : \(100\) ns.

Question : temps total d’accès aux \(100\) entiers.

Correction

  • Une ligne \(= 64/4 = 16\) entiers ; \(100/16 = 6{,}25\), donc \(7\) lignes.
  • Premier accès de chaque ligne : défaut ; les suivants dans la même ligne : succès.
  • \(7\) défauts \(\times 100\) ns \(= 700\) ns ; \(93\) succès \(\times 1\) ns \(= 93\) ns.
  • Total : \(793\) ns.

Sans cache : \(100 \times 100 = 10\,000\) ns : le cache divise le temps par \(12{,}6\).

Observation : grâce à la localité spatiale, seulement \(7\,\%\) de défauts. La septième ligne ne contient que \(4\) entiers utiles sur \(16\).

Cent entiers parcourus, pas à pas

Sortie \(\rightarrow\)

7 93 793

Lecture. \(i=0\) : t[0] est à l’adresse \(0\), dans la ligne \(0\), absente : défaut ; la ligne entière (t[0] à t[15]) est chargée (rouge : modifiée).

Lecture. \(i=1\) : adresse \(4\), toujours la ligne \(0\), examinée (orange) et présente : succès. Le défaut précédent a apporté les voisins : c’est la localité spatiale.

Lecture. \(i=15\) : adresse \(60\), dernier entier de la ligne \(0\) : quinze succès de suite après un seul défaut.

Lecture. \(i=16\) : adresse \(64\), ligne \(1\), absente : deuxième défaut, la ligne \(1\) est chargée. Le motif se répète toutes les \(16\) itérations.

Lecture. Fin de boucle (\(i=99\), adresse \(396\), ligne \(6\)) : \(7\) lignes touchées, donc \(7\) défauts et \(93\) succès ; la ligne \(6\) ne sert qu’à \(4\) entiers sur \(16\).

Lecture. Ligne 10 : \(7\times100+93\times1=793\) ns, contre \(100\times100=10\,000\) ns sans cache : \(12{,}6\) fois moins. Taux de défauts : \(7/100=7\,\%\).

Métriques de performance

Temps d’exécution et accélération

Temps d’exécution sur \(n\) processeurs et accélération ({speedup})

\[ T(n) = T_s + \frac{T_p}{n} + T_{\text{surcoût}} \]

\[ S(n) = \frac{T(1)}{T(n)} = \frac{T_s + T_p}{T_s + \frac{T_p}{n}} \]

\(T_s\) : séquentiel ; \(T_p\) : parallélisable ; \(T_{\text{surcoût}}\) : synchronisation, communication ; seconde égalité sans surcoût ; les labs notent \(p\) le nombre de processus.

Lecture. Seule la partie parallélisable se partage : \(S(4)=100/36{,}5=2{,}74\), au lieu de \(3{,}08\) sans surcoût.

Accélération idéale et réelle

Idéal : \(S(n)=n\), le programme va \(n\) fois plus vite avec \(n\) processeurs.

En pratique, \(S(n)<n\) à cause de :

  • la partie séquentielle ;
  • le surcoût de la parallélisation ;
  • les conflits d’accès à la mémoire ;
  • le déséquilibre de charge.

Lecture. Avec \(f=10\,\%\) de séquentiel, \(16\) processeurs donnent \(6{,}40\), et la courbe ne dépassera jamais \(10\). Chaque courbe plafonne à \(1/f\) (pointillés).

Efficacité

Efficacité

\[ E(n) = \frac{S(n)}{n} = \frac{T(1)}{n \times T(n)} \]

Part du travail des \(n\) processeurs réellement utile.

  • \(E(n)=1\) : utilisation parfaite (\(100\,\%\)) ;
  • \(E(n)=0{,}5\) : utilisation à \(50\,\%\) ;
  • \(E(n)<0{,}5\) : généralement jugé inefficace.

Exemple

Un programme de \(100\) s dure \(30\) s sur \(4\) processeurs : \(S=100/30=3{,}33\), \(E=3{,}33/4=0{,}83\). Chaque processeur a travaillé utilement \(83\,\%\) du temps ; le reste est perdu en attente et en coordination.

Au-delà de 100 %

Rarement, \(E>1\) : en découpant les données, chaque part tient dans le cache de son cœur (accélération superlinéaire). C’est l’exception.

Exercice : lecture d’une mesure

Énoncé

Un programme s’exécute en \(120\) s en séquentiel, en \(40\) s avec \(4\) processeurs. Calculer :

  1. l’accélération ;
  2. l’efficacité ;
  3. la fraction séquentielle approximative ;
  4. commenter.

Correction

  1. \(S(4) = 120/40 = \mathbf{3}\).
  2. \(E(4) = 3/4 = \mathbf{0{,}75}\), soit \(75\,\%\).
  3. Loi d’Amdahl à l’envers : \(3 = \dfrac{1}{f + \frac{1-f}{4}}\), donc \(f + \dfrac{1-f}{4} = \dfrac13\), \(4f + 1 - f = \dfrac43\), \(3f = \dfrac13\), \(\mathbf{f = 1/9 \approx 11\,\%}\).
  4. Accélération de \(3\) au lieu de \(4\) ; efficacité correcte mais perfectible ; \(11\,\%\) de séquentiel limitent déjà nettement le gain. Causes possibles : synchronisation, accès à la mémoire partagée.

Loi d’Amdahl

La loi d’Amdahl (1967)

Loi d’Amdahl

Soit \(f\) la fraction séquentielle du programme (\(0 \le f \le 1\)) :

\[ S(n) = \frac{1}{f + \frac{1-f}{n}} \]

Accélération maximale (\(n \to \infty\)) : \(S_{\max} = \dfrac{1}{f}\).

Interprétation : si \(5\,\%\) du programme est séquentiel (\(f=0{,}05\)), l’accélération maximale est \(20\), même avec un million de processeurs.

Analogie

La loi d’Amdahl dit une vérité fondamentale : on ne peut pas paralléliser ce qui est intrinsèquement séquentiel. C’est comme une chaîne de production : peu importe le nombre d’ouvriers, si une étape doit être faite par une seule personne, elle devient le goulot d’étranglement.

La formule vient de \(T(n)=T_s+T_p/n\) avec \(T(1)=1\), \(T_s=f\) et \(T_p=1-f\).

La loi d’Amdahl en frise, pas à pas

Lecture. \(n=1\) : le programme dure \(100\) s, dont \(10\) s de partie séquentielle (violet) et \(90\) s de partie parallélisable (bleu) ; \(S(1)=1\).

Lecture. \(n=2\) : seule la partie parallèle se partage : \(10+90/2=55\) s, \(S(2)=100/55=1{,}82\).

Lecture. \(n=4\) : \(10+90/4=32{,}5\) s, \(S(4)=3{,}08\). La partie séquentielle fait déjà près du tiers du temps.

Lecture. \(n=8\) : \(10+90/8=21{,}25\) s, \(S(8)=4{,}71\). Doubler \(n\) ne fait plus gagner que \(11{,}25\) s.

Lecture. \(n\to\infty\) : \(90/n\to0\), il reste les \(10\) s séquentielles : \(S\to100/10=10=1/f\). L’accélération plafonne à \(10\).

Exemples pratiques

\(f\) (séq.) \(S(2)\) \(S(10)\) \(S(100)\) \(S(\infty)\)
\(0\,\%\) \(2{,}00\) \(10{,}00\) \(100{,}00\) \(\infty\)
\(5\,\%\) \(1{,}90\) \(6{,}90\) \(16{,}81\) \(20\)
\(10\,\%\) \(1{,}82\) \(5{,}26\) \(9{,}17\) \(10\)
\(20\,\%\) \(1{,}67\) \(3{,}57\) \(4{,}81\) \(5\)
\(50\,\%\) \(1{,}33\) \(1{,}82\) \(1{,}98\) \(2\)

Calcul d’une case, \(f=5\,\%\) et \(n=100\) :

\[ S(100)=\frac{1}{0{,}05+\frac{0{,}95}{100}}=\frac{1}{0{,}0595}=16{,}81 \]

Lecture. Avec \(5\,\%\) de séquentiel, \(100\) processeurs ne donnent que \(16{,}81\), à peine \(17\,\%\) de l’idéal. Les petites fractions séquentielles coûtent cher dès que \(n\) grandit.

Exercice : 15 % de séquentiel

Énoncé

Un programme a une partie séquentielle de \(15\,\%\).

  1. Accélération avec \(4\) processeurs.
  2. Avec \(16\) processeurs.
  3. Accélération maximale.
  4. Nombre de processeurs pour atteindre \(90\,\%\) du maximum.
  5. Doubler le nombre de processeurs double-t-il l’accélération ?

Correction (\(f=0{,}15\))

  1. \(S(4)=\dfrac{1}{0{,}15+\frac{0{,}85}{4}}=\dfrac{1}{0{,}3625}=\mathbf{2{,}76}\).
  2. \(S(16)=\dfrac{1}{0{,}15+0{,}053125}=\dfrac{1}{0{,}203125}=\mathbf{4{,}92}\).
  3. \(S_{\max}=1/0{,}15=\mathbf{6{,}67}\).
  4. \(90\,\%\) de \(6{,}67\) vaut \(6\) : \(0{,}15+\dfrac{0{,}85}{n}=\dfrac16\), donc \(\dfrac{0{,}85}{n}=\dfrac{1}{60}\) et \(n=0{,}85\times60=\mathbf{51}\) (en fractions ; arrondir \(1/6\) à \(0{,}167\) donnerait \(50\)).
  5. Non : \(S(8)=3{,}90\), soit \(+41\,\%\) de \(4\) à \(8\) ; \(S(16)=4{,}92\), soit \(+26\,\%\) de \(8\) à \(16\). Les rendements sont décroissants.

Loi de Gustafson

Une vision plus optimiste

La loi d’Amdahl suppose que la taille du problème est fixe. Gustafson (1988) propose une autre vision : quand on a plus de processeurs, on traite des problèmes plus grands.

Les deux lois ne posent pas la même question :

  • Amdahl : avec \(n\) processeurs, en combien de temps ce problème est-il résolu ?
  • Gustafson : avec \(n\) processeurs, quelle taille de problème est traitée dans le même temps ?

Différence clé :

  • Amdahl : problème fixe \(\Rightarrow\) accélération limitée ;
  • Gustafson : temps fixe \(\Rightarrow\) problème plus grand ;
  • Amdahl est pessimiste, Gustafson optimiste.

Loi de Gustafson

Le temps d’exécution est fixe. Si \(s\) est la fraction du temps passé en séquentiel sur \(n\) processeurs :

\[ S(n) = s + n(1-s) = n - s(n-1) \]

Elle mesure combien de travail supplémentaire on accomplit avec plus de processeurs.

Amdahl et Gustafson en frise, pas à pas

Lecture. \(n=1\) : les deux lois partent du même programme, \(0{,}1\) de séquentiel et \(0{,}9\) de parallélisable, pour une durée de \(1\) ; \(S=1\).

Lecture. \(n=2\) : Amdahl garde le problème et partage le \(0{,}9\) : durée \(0{,}55\), \(S=1{,}82\). Gustafson garde la durée \(1\) et donne \(0{,}9\) de travail à chaque processeur : \(0{,}1+2\times0{,}9=1{,}9\), \(S=1{,}9\).

Lecture. \(n=4\) : Amdahl : \(0{,}1+0{,}9/4=0{,}325\), \(S=3{,}08\). Gustafson : \(0{,}1+4\times0{,}9=3{,}7\), \(S=3{,}7=4-0{,}1\times3\).

Lecture. \(n=8\) : Amdahl : \(0{,}2125\), \(S=4{,}71\) ; le violet pèse de plus en plus. Gustafson : \(7{,}3=8-0{,}1\times7\) ; le séquentiel ne pèse plus que \(0{,}1/7{,}3\approx1{,}4\,\%\) du travail.

Exercice : comparaison des deux lois

Énoncé

Avec \(10\,\%\) de code séquentiel et \(16\) processeurs :

  1. accélération selon Amdahl ;
  2. accélération selon Gustafson ;
  3. expliquer la différence ;
  4. dans quel contexte chaque loi est-elle pertinente ?

Correction

  1. \(f=0{,}1\) : \(S=\dfrac{1}{0{,}1+\frac{0{,}9}{16}}=\dfrac{1}{0{,}15625}=\mathbf{6{,}4}\).
  2. \(s=0{,}1\) : \(S=16-0{,}1\times(16-1)=16-1{,}5=\mathbf{14{,}5}\).
  3. Amdahl parallélise un problème de taille fixe : le gain plafonne. Gustafson emploie les \(16\) processeurs à traiter, dans le même temps, un problème \(14{,}5\) fois plus grand ; il suppose que la taille suit les ressources.
  4. Amdahl : traitements de taille fixe (compilation, rendu d’une vidéo donnée). Gustafson : simulation scientifique, apprentissage automatique (plus de données, meilleurs résultats).

Granularité et surcoût

La granularité des tâches

Granularité d’une tâche

Rapport entre calcul et communication d’une tâche :

\[ G = \frac{T_{\text{calcul}}}{T_{\text{communication}}} \]

\(T_{\text{communication}}\) : création, synchronisation, communication. \(G\) fixe la taille des unités de travail parallèle.

Trois types de granularité :

  • fine (\(G<1\)) : petites tâches, beaucoup de communication ;
  • moyenne (\(1\le G<100\)) : équilibre entre calcul et communication ;
  • grosse (\(G\ge100\)) : grandes tâches, peu de communication.

Analogie : un déménagement entre amis

  • fine : chacun porte un livre à la fois : allers-retours, coordination, embouteillage dans l’escalier ;
  • moyenne : chacun porte une boîte de livres : effort et coordination s’équilibrent ;
  • grosse : chacun vide une pièce entière : peu de coordination, mais personne ne peut aider celui qui finit en retard.

L’effet de la granularité sur les performances

Lecture. Fine : \(10/11=91\,\%\) du temps en surcoût. Moyenne : \(0{,}1/1{,}1=9\,\%\). Grosse : \(12\) processeurs sur \(16\) restent inactifs, efficacité de \(4/16=25\,\%\).

Le surcoût du parallélisme

Surcoût ({overhead})

Temps supplémentaire nécessaire pour gérer le parallélisme, qui n’existe pas dans la version séquentielle : c’est le coût de la parallélisation.

Le surcoût comprend :

  • la création et la destruction des processus ou des fils d’exécution (jusqu’à plusieurs millisecondes) ;
  • la synchronisation : attentes, verrous, barrières ;
  • la communication entre processus (latence du réseau, copies en mémoire) ;
  • le déséquilibre de charge (processeurs inactifs) ;
  • la contention mémoire (accès concurrents au bus).

Lecture. Le Lab 2 mesure ce surcoût : il fait payer le prix des tâches trop petites confiées à plusieurs processus.

Exercice : choix d’un découpage

Énoncé

Un calcul matriciel se découpe de deux façons :

  • option A : \(1000\) tâches de \(1\) ms, surcoût de \(0{,}1\) ms par tâche ;
  • option B : \(10\) tâches de \(100\) ms, surcoût de \(1\) ms par tâche.

Avec \(4\) processeurs, quelle option est la meilleure ? Et avec \(100\) processeurs ?

Correction

Avec 4 processeurs

  • A : \(1000\times1{,}1 = 1100\) ms de travail, \(250\) tâches par processeur : \(\mathbf{275}\) ms. Granularité \(G=1/0{,}1=10\) (moyenne).
  • B : \(10\times101=1010\) ms de travail ; deux processeurs font \(3\) tâches (\(303\) ms), deux en font \(2\) (\(202\) ms) : \(\mathbf{303}\) ms. \(G=100\) (grosse).
  • A est meilleure (\(275\) contre \(303\) ms).

Avec 100 processeurs

  • A : \(10\) tâches par processeur : \(\mathbf{11}\) ms.
  • B : \(10\) tâches pour \(100\) processeurs, \(90\) inactifs : \(\mathbf{101}\) ms.
  • A est largement meilleure. Leçon : la granularité optimale dépend du nombre de processeurs.

Deux découpages, pas à pas

Sortie \(\rightarrow\)

303   275   101   11

Lecture. Ligne 7, découpage B sur \(4\) cœurs. Tâche \(1\) : fin\(=[0,0,0,0]\), min désigne le cœur \(0\), qui finit à \(100+1=101\) ms.

Lecture. Tâches \(2\) à \(4\) : chacune va au cœur libre le plus tôt, les cœurs \(1\), \(2\), \(3\) : fin\(=[101,101,101,101]\).

Lecture. Tâches \(5\) à \(8\) : deuxième tour : fin\(=[202,202,202,202]\).

Lecture. Tâches \(9\) et \(10\) : les cœurs \(0\) et \(1\) en font \(3\) et finissent à \(303\) ms, les cœurs \(2\) et \(3\) en font \(2\) et attendent dès \(202\) ms. Répartition \(3/3/2/2\) : B dure \(303\) ms.

Lecture. Ligne 8, découpage A sur \(4\) cœurs : \(250\) tâches de \(1{,}1\) ms par cœur, \(275\) ms, sans attente. A gagne malgré dix fois plus de surcoût total (\(100\) ms contre \(10\)).

Lecture. Lignes 9 et 10, sur \(100\) cœurs : B n’a que \(10\) tâches, \(90\) cœurs restent inactifs et la durée reste \(101\) ms ; A donne \(10\) tâches à chaque cœur : \(11\) ms.

À retenir

À retenir (1/2)

  1. Le parallélisme est nécessaire : la fréquence ne monte plus (mur thermique, \(P=C\,V^2f\)) ; les transistors servent à multiplier les cœurs.
  2. Flynn : SISD séquentiel, SIMD vectoriel (GPU), MISD rare (redondance), MIMD multicœurs.
  3. Hiérarchie mémoire : le cache est indispensable ; il charge des lignes de \(64\) octets et exploite la localité temporelle et spatiale ; rapport d’environ \(1\) à \(100\) entre cache et RAM.

À retenir (2/2)

  1. Métriques : \(T(n)=T_s+T_p/n+T_{\text{surcoût}}\), \(S(n)=T(1)/T(n)\), \(E(n)=S(n)/n\).
  2. Amdahl : le séquentiel limite l’accélération, \(S_{\max}=1/f\).
  3. Gustafson : avec plus de ressources, on traite un problème plus grand, \(S(n)=n-s(n-1)\).
  4. Granularité : l’équilibre entre calcul et communication décide de l’efficacité ; il dépend du nombre de processeurs.

Questions de révision

Vrai ou faux

  1. Un processeur SIMD exécute plusieurs programmes différents à la fois.
  2. La SRAM est plus rapide mais plus chère que la DRAM.
  3. Avec \(10\,\%\) de séquentiel, l’accélération maximale est \(10\) (Amdahl).
  4. La granularité fine est toujours préférable.
  5. Le cache exploite la localité temporelle et spatiale.
  6. Gustafson est plus optimiste qu’Amdahl.
  7. L’efficacité peut dépasser \(100\,\%\).

Correction

  1. Faux : SIMD applique la même instruction à plusieurs données.
  2. Vrai.
  3. Vrai : \(S_{\max}=1/0{,}1=10\).
  4. Faux : le surcoût finit par dépasser le calcul.
  5. Vrai.
  6. Vrai.
  7. Vrai, rarement : accélération superlinéaire, quand chaque part des données tient dans le cache de son cœur.

Labs et prochaine séance

Les labs de la séance

  • Lab 0, prise en main : Anaconda, Jupyter, fonctions, lambda et map, mesure du temps, NumPy, fils et processus.
  • Lab 1, penser parallèle : map, reduce, tâches indépendantes, compter les mots de huit textes avec plusieurs processus.
  • Lab 2, plusieurs cœurs : multiprocessing, accélération mesurée, prix des tâches trop petites, loi d’Amdahl confrontée à la mesure, \(\pi\) par Monte-Carlo.

Prochaine séance

Séance 2 : cohérence de cache et protocoles. Chaque cœur a ses propres caches : quand deux cœurs utilisent la même donnée, comment garantir qu’ils en voient la même valeur ? Protocoles MSI et MESI, false sharing (faux partage), cohérence séquentielle. Lab 3 : la mémoire.

Références

  • Hennessy, J. L., Patterson, D. A. Computer Architecture: A Quantitative Approach, 6e éd. Morgan Kaufmann, 2017 (ch. 1 : tendances, puissance, loi d’Amdahl ; ch. 2 et annexe B : hiérarchie mémoire et caches ; ch. 4 : SIMD).
  • Pacheco, P. S., Malensek, M. An Introduction to Parallel Programming, 2e éd. Morgan Kaufmann, 2022 (ch. 2 : Flynn, caches, accélération, efficacité, Amdahl, Gustafson).
  • Grama, A., Gupta, A., Karypis, G., Kumar, V. Introduction to Parallel Computing, 2e éd. Addison-Wesley, 2003 (ch. 3 et 5 : granularité, surcoût).
  • Flynn, M. J. Very high-speed computing systems. Proceedings of the IEEE, 54(12), 1966. Amdahl, G. M. Validity of the single processor approach to achieving large scale computing capabilities. AFIPS, 1967. Gustafson, J. L. Reevaluating Amdahl’s law. Communications of the ACM, 31(5), 1988.

Données de l’évolution des processeurs : K. Rupp, 50 Years of Microprocessor Trend Data (1971–2021, licence CC BY 4.0). Chiffres matériels : Intel (Pentium 4 570J, \(3{,}8\) GHz, novembre 2004) ; AMD, présentation de l’architecture Zen 4, août 2022 (L2 en \(14\) cycles, L3 en \(50\) cycles).