172 lines
5.5 KiB
TeX
172 lines
5.5 KiB
TeX
|
%\part{Cours 1\er}
|
||
|
|
||
|
\chapter{Introduction}
|
||
|
|
||
|
\section{Motivations}
|
||
|
|
||
|
On augmente plus trop en fréquence, ça augmente plus trop ces dernières années
|
||
|
comparé à avant. Et pourtant, on augmente toujours le nombre de processeurs sur
|
||
|
les puces. On va de plus en plus vers du parallélisme et non plus vers de la
|
||
|
vitesse.
|
||
|
|
||
|
\section{Vocabulaire}
|
||
|
|
||
|
\subsection{Modèle d'exécution}
|
||
|
|
||
|
\subsubsection{À acteurs}
|
||
|
|
||
|
Ils communiquent entre-eux~: au lieu d'éxécuter le code d'un objet dans le
|
||
|
thread courant, la méthode s'éxécute dans le thread de l'objet. Similaire au
|
||
|
RPC.
|
||
|
|
||
|
\subsubsection{Futures}
|
||
|
|
||
|
Notion d'éxécution lazy. Le calcul commence en tâche de fond, lorsque l'on a
|
||
|
besoin de la valeur, on est mis en attente si elle n'est pas encore calculée~;
|
||
|
on a donc pas à attendre au début du calcul.
|
||
|
|
||
|
\subsubsection{CSP -- Communication Séquential Processors}
|
||
|
|
||
|
Modèle dans lequel on a des processus séquentiel qui ne font que se parler (pas
|
||
|
de mémoire partagée).
|
||
|
|
||
|
\subsubsection{CCS}
|
||
|
|
||
|
?
|
||
|
|
||
|
\subsection{Gestion des sections critiques}
|
||
|
|
||
|
\subsubsection{Locks}
|
||
|
\subsubsection{Conditions}
|
||
|
\subsubsection{Mutex}
|
||
|
\subsubsection{Sémaphores}
|
||
|
|
||
|
\subsection{Histoire}
|
||
|
|
||
|
Apparu vers la fin des années 50. Premier aboutissement (machine à 4
|
||
|
processeurs) en 1962.
|
||
|
|
||
|
\subsection{Définitions}
|
||
|
|
||
|
\subsubsection{Matérielle}
|
||
|
|
||
|
\paragraph{Symetric MultiProcessor} On place plusieurs processeurs (identiques
|
||
|
ou non) sur une carte mère spéciale.
|
||
|
|
||
|
\paragraph{Multi-core} deux processeurs ou plus en un, avec certain composants
|
||
|
partagés~: en particulier les caches. Moins cher que du SMP
|
||
|
|
||
|
\paragraph{Hyper-threading} Étant donné que chaque famille d'instruction a une
|
||
|
zone réservée dans le processeur, du coup, lorsqu'une instruction est en train
|
||
|
de s'exécuter, elle bloque le reste du processeur, du coup, beaucoup de circuit
|
||
|
ne servent pas, l'hyperthreading essaye d'exécuter plusieurs zone en même
|
||
|
temps.
|
||
|
|
||
|
\paragraph{Vectorized instructions} applique une instruction sur un lot de
|
||
|
donnée.
|
||
|
|
||
|
\paragraph{Non-Uniform Memory Access (\textsc{numa})} on associe à chaque
|
||
|
processeur des blocs mémoires. Un certain processeur a un accès prioritaire à
|
||
|
ses blocs mémoires.
|
||
|
|
||
|
|
||
|
\chapter{Soyons parallèle}
|
||
|
|
||
|
\section{Gain~?}
|
||
|
|
||
|
Amdahl's law~: $$\frac{1}{(1-P\frac{P}{N}}$$
|
||
|
|
||
|
On n'ira jamais deux fois plus vite que deux fois plus vite avec 50\% du code
|
||
|
parallélisé. Au final, il faut s'arranger sur la parallélisation du code,
|
||
|
plutôt que sur le nombre de processeurs.\\
|
||
|
|
||
|
Gustafson's law~: $$S(P)=P+a\times(P-1)$$
|
||
|
|
||
|
\section{Différents types de parallélisme}
|
||
|
|
||
|
\subsection{Décomposition par tâches}
|
||
|
|
||
|
On lance un thread par tâche en gros. Il faut voir les problèmes
|
||
|
d'interdépendances entre chaque thread, etc.
|
||
|
|
||
|
\subsection{Data driven}
|
||
|
|
||
|
On a un paquet de données similaire. On a un traitement similaire à effectuer
|
||
|
sur ces données.
|
||
|
|
||
|
On découpe les données en petits blocs et on lance plein de petit threads.
|
||
|
|
||
|
\subsection{Modèle flow}
|
||
|
|
||
|
Comme une chaîne de production. On a $n$ tâche, chaque unité traite une
|
||
|
tâche. Pour que ça marche, il faut que les données soient correctement découpés.
|
||
|
|
||
|
\subsection{Design Patterns}
|
||
|
|
||
|
\paragraph{Divide and Conquer} on divise le problème, puis on a une seconde
|
||
|
phase de recollection des données.
|
||
|
|
||
|
\paragraph{Pipeline} mise en pratique de la décomposition par data flow.
|
||
|
|
||
|
\paragraph{Wave front} mise en œuvre d'un tri topologique parallélisée. On
|
||
|
traite une tâche quand on a traitée ses prédécesseurs.
|
||
|
|
||
|
\paragraph{Geometric decomposition} façon de couper les blocs de données qui ne
|
||
|
sont pas forcément contigus.
|
||
|
|
||
|
|
||
|
\chapter{Interragir avec le cache du CPU}
|
||
|
|
||
|
Le cache est nécessaire du fait que la mémoire est beaucoup plus lente que le
|
||
|
processeur.
|
||
|
|
||
|
Le cache est géré par ligne~: de quelques dizaine d'octets. Chaque ligne a un
|
||
|
état par rapport à sa cohérence. Lorsqu'elle est invalide cela signifie qu'une
|
||
|
modification a été effectuée en mémoire ou dans un autre cache (d'un autre
|
||
|
processeur par exemple). En état partagé, il n'est pas possible d'écrire
|
||
|
dessus, on peut seulement la lire. En mode exclusif, seul un processeur peut
|
||
|
écrire la zone mémoire, elle est ensuite noté modified.
|
||
|
|
||
|
\section{False sharing}
|
||
|
|
||
|
Par moment, il peut y avoir deux processeurs qui utilisent deux valeurs
|
||
|
différentes mais dans des lignes de cache identiques. Du coup il va invalider
|
||
|
une ligne de cache sur l'autre processeur alors qu'en réalité, la valeur qui
|
||
|
intéressait le processeur n'a pas été modifiée. On parle de \emph{False
|
||
|
sharing}.
|
||
|
|
||
|
Pour éviter ce genre de chose, il faut utiliser le plus de variable locale
|
||
|
possible dans chaque thread, et avoir le moins de données communes.\\
|
||
|
|
||
|
\section{Memory fence}
|
||
|
|
||
|
|
||
|
\chapter{Exclusion mutuelle}
|
||
|
|
||
|
Une section critique est une section de code où l'on manipule des données
|
||
|
partagées (quand on dépend d'événement d'écriture sur une zone mémoire).
|
||
|
|
||
|
\section{Problème classique~: compteur partagé}
|
||
|
|
||
|
On a un compteur partagé entre deux threads.
|
||
|
|
||
|
|
||
|
\paragraph{Exclussion mutuelle~:} deux threads ne doivent pas pouvoir être au même endroit
|
||
|
en même temps.
|
||
|
|
||
|
\paragraph{Progression~:} lorsque l'on veut aller dans une section critique, on ne doit
|
||
|
attendre que parce que quelqu'un y est déjà.
|
||
|
|
||
|
\paragraph{Attente bornée~:} quand on attend la section critique. On attend un nombre fini
|
||
|
de thread.
|
||
|
|
||
|
\paragraph{Deadlock~:} mauvaise combinaison d'accès du coup deux thread s'attendent
|
||
|
mutuellement.
|
||
|
|
||
|
\paragraph{Race condition~:} sous certaines conditions d'éxécution, certaines propriétés ne
|
||
|
sont pas respectées.
|
||
|
|
||
|
\paragraph{Famine~:} un thread est en famine quand il attend indéfiniment une
|
||
|
ressources.
|
||
|
|