01.07.2013 Views

IPD TP1 - Enonce 2012-2013.pdf

IPD TP1 - Enonce 2012-2013.pdf

IPD TP1 - Enonce 2012-2013.pdf

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Travaux pratique d'Informatique Parallèle et Distribuée, UMONS/Polytech, TP 1 1<br />

1.Programmation de systèmes à mémoire partagée avec l'API OpenMP<br />

1.1.Objectifs<br />

Les objectifs de la séance sont de:<br />

1.2.Généralités<br />

● se familiariser avec la syntaxe d'OpenMP<br />

● réaliser des programmes multi­threadés exploitant les multiples cores/processeurs<br />

OpenMP est une API permettant la programmation d'applications parallèles à mémoire partagée<br />

en langage C/C++ ou Fortran.<br />

Son fonctionnement repose sur la définition de sections de code parallèles permettant un partage<br />

du calcul à réaliser et d'un ensemble d'étapes de synchronisation. L'exécution est multi­threadée et n'a<br />

donc d'intérêt que sur des machines à mémoire partagée multi­processeurs et/ou multi­cores (ce qui est le<br />

cas des PC utilisés dans la salle informatique).<br />

De nombreux compilateurs open source (e.g. gcc à partir de la version 4.2) et propriétaires (e.g.<br />

IBM, Intel, Portland Group) implémentent la spécification OpenMP.<br />

1.3.Généralités sur la programmation multi-threadée<br />

Un programme multi­threadé se caractérise par un ensemble de fils d'exécution se déroulant<br />

simultanément sur des unités de traitements différentes (core/processeur) au sein d'un unique processus.<br />

L'ordonnancement des fils d'exécution et le partage du temps de calcul sur la machine sont réalisés par le<br />

système d'exploitation (e.g. le noyau Linux).<br />

La création d'une telle application nécessite donc d'identifier les sections denses en terme de<br />

quantité de calculs et de déterminer une manière de diviser le travail en différentes parties. Le processus<br />

principal (thread principal) donne alors naissance à un ensemble de threads qui s'exécutent en parallèle:<br />

Thread<br />

principal<br />

Section<br />

parallèle<br />

Thread<br />

principal<br />

FORK JOIN<br />

(synchronisation)<br />

UMONS/Polytech<br />

Pierre Manneback, Sébastien Frémal, Sébastien Noël <strong>2012</strong>­13


Travaux pratique d'Informatique Parallèle et Distribuée, UMONS/Polytech, TP 1 2<br />

1.4.Utilisation d'OpenMP avec gcc<br />

Lors des séances de TP, nous utiliserons le compilateur GNU gcc en spécifiant l'option de<br />

compilation ­fopenmp afin de lui permettre d'interpréter les directives OpenMP. La compilation d'un<br />

code code.c se fera donc de la manière suivante:<br />

gcc code.c ­o executable ­fopenmp<br />

L'en­tête omp.h doit également être inclus en début de code:<br />

#include <br />

Une section parallèle OpenMP est spécifiée par une construction du type:<br />

#pragma omp parallel<br />

{<br />

...<br />

}<br />

Lorsqu'un thread principal atteint une section parallèle, il crée un groupe de n threads dont il<br />

devient le maître. Le nombre n de threads créés dépend du nombre d'unités de traitement sur la machine<br />

utilisée. Implicitement, les threads s'attendent mutuellement en sortie d'une section parallèle sauf si<br />

l'option nowait à été spécifiée dans la déclaration de la section:<br />

#pragma omp parallel nowait<br />

Les variables déclarées avant la section parallèle et devant être manipulées par les threads sont<br />

spécifiées dans la déclaration de la section parallèle en tant que partagée (shared) ou privée (private):<br />

#pragma omp parallel private(i,j) → chaque thread dispose d'une copie locale de i et j<br />

#pragma omp parallel shared(n) → chaque thread partage l'accès à une unique variable n<br />

Une opération de réduction (e.g. somme globale) peut être opérée sur une variable: de cette<br />

manière, chaque thread travaille sur une variable privée et une réduction de la valeur des variables est<br />

opérée en sortie de la section parallèle:<br />

#pragma omp parallel reduction(+:i)<br />

→ chaque thread dispose d'une copie de i et la somme<br />

de toutes les valeurs de i est réalisée en sortie de<br />

section parallèle<br />

Un test peut être réalisé si l'on souhaite conditionner la création d'un groupe de threads suivant la<br />

valeur d'un paramètre donné:<br />

#pragma omp parallel if ( n > 3 )<br />

→ le groupe de threads n'est créé que si le test est vrai<br />

UMONS/Polytech<br />

Pierre Manneback, Sébastien Frémal, Sébastien Noël <strong>2012</strong>­13


Travaux pratique d'Informatique Parallèle et Distribuée, UMONS/Polytech, TP 1 3<br />

a) Partage du travail<br />

Quatre « schémas » sont mis à disposition par OpenMP pour diviser le travail entre les différents<br />

threads au sein d'une section parallèle:<br />

#pragma omp for<br />

for(i=0;i


Travaux pratique d'Informatique Parallèle et Distribuée, UMONS/Polytech, TP 1 4<br />

• Barrier<br />

Une autre directive permet de synchroniser tous les threads de la section parallèle en attendant<br />

que tous atteignent un certain point dans le programme:<br />

#pragma omp barrier<br />

c) Fonctions OpenMP<br />

Un ensemble de fonctions est mis à disposition pour réaliser certaines opérations sur<br />

l'environnement OpenMP.<br />

void omp_set_num_threads(int num_threads) Spécifie le nombre de threads à utiliser (doit être<br />

déclaré avant une section parallèle)<br />

int omp_get_num_threads(void) Retourne le nombre de threads dans la section<br />

parallèle<br />

int omp_get_thread_num(void) Retourne le numéro du thread appelant<br />

int omp_get_num_procs(void) Retourne le nombre d'unités de traitement<br />

double omp_get_wtime(void) Retourne le nombre de secondes écoulées<br />

UMONS/Polytech<br />

Pierre Manneback, Sébastien Frémal, Sébastien Noël <strong>2012</strong>­13


Travaux pratique d'Informatique Parallèle et Distribuée, UMONS/Polytech, TP 1 5<br />

1.5.Exercices<br />

a) Exercice 1<br />

Écrire un programme affichant un message quelconque(e.g. « Hello world »).<br />

Intégrer cet affichage à une section parallèle et ajouter au message les informations suivantes:<br />

● le nombre de threads créés<br />

● le numéro du thread affichant le message<br />

● le nombre d'unités de traitement sur la machine utilisée<br />

Ajouter ensuite une boucle parallèle afin d'afficher le message 10 fois.<br />

b)Exercice 2.1<br />

On souhaite réaliser un programme capable de calculer la somme des nombres premiers<br />

inférieurs à une valeur donnée n.<br />

La valeur de n sera passée comme argument dans la ligne de commande:<br />

./ex1 100000<br />

aura pour effet de calculer la somme des nombres premiers inférieurs à 100000 (remarque: en<br />

vue de tester votre programme, le résultat à trouver vaut : 454396537).<br />

Dans un premier temps, aucune directive OpenMP ne sera utilisée, le programme étant alors<br />

exécuté séquentiellement.<br />

Observer le temps d'exécution à l'aide de la commande unix time.<br />

c) Exercice 2.2<br />

time ./ex1 100000<br />

Paralléliser l'exercice 1 à l'aide d'une boucle parallèle OpenMP et d'une variable partagée.<br />

Remarque:<br />

● Protéger l'accès à la variable partagée result.<br />

● Tester différentes politiques d'ordonnancement à l'aide de l'option schedule et<br />

observer leur impact sur le temps de calcul.<br />

d)Exercice 2.3<br />

Utiliser la directive reduction pour remplacer la variable partagée result.<br />

UMONS/Polytech<br />

Pierre Manneback, Sébastien Frémal, Sébastien Noël <strong>2012</strong>­13


Travaux pratique d'Informatique Parallèle et Distribuée, UMONS/Polytech, TP 1 6<br />

e) Exercice 3<br />

Lire et comprendre le premier programme séquentiel fourni en annexe.<br />

Ce programme permet la création d'un tableau de particules positionnées aléatoirement dans un<br />

espace virtuel à 3 dimensions. Le nombre de particules est fourni en argument au lancement du<br />

programme. La distance entre les particules prises 2 à 2 est ensuite évaluée et le programme fournit le<br />

numéro des 2 particules les plus proches ainsi que la distance qui les sépare.<br />

Paralléliser ce programme en utilisant les directives OpenMP afin d'obtenir le meilleur temps<br />

d'exécution.<br />

Estimer le nombre minimum de particules en dessous duquel la parallélisation n'améliore pas les<br />

performances; introduire alors un test « if » sur ce nombre minimum conditionnant la création des<br />

threads.<br />

f) Exercice 4<br />

Lire et comprendre le second programme séquentiel fourni en annexe.<br />

Ce programme calcul le nombre de partitions de x en au plus y parties (noté d(x,y)), ce qui<br />

signifie qu'il calcule le nombre de combinaisons d'au plus y chiffres et dont la somme vaut x. Exemple :<br />

d(5,3) = {5} + {4+1} + {3+2} + {1+1+3} + {1+2+2} = 5<br />

Soit d'(x,y) le nombre de partitions qui comprennent exactement y chiffres (soit 2 dans notre<br />

exemple si y vaut 3), alors d(x,y) = d'(x,y) + d(x,y­1) (nombre de partitions de x en au plus y parties =<br />

nombre de partitions de x en exactement y parties + nombre de partitions de x en au plus (y­1) parties).<br />

Il a été démontré que d'(x,y) = d(x­y,y) 1 et ainsi :<br />

d(x,y) = d(x­y,y) + d(x,y­1)<br />

Paralléliser ce programme en utilisant les directives OpenMP afin d'optimiser le temps de calcul.<br />

1. S. Skiena, Implementing Discrete Mathematics: Combinatorics and Graph Theory<br />

with Mathematica. Reading, MA: Addison­Wesley, 1990, p.58<br />

UMONS/Polytech<br />

Pierre Manneback, Sébastien Frémal, Sébastien Noël <strong>2012</strong>­13

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!