Vous êtes sur la page 1sur 6

Programmation Parallèle et Distribuée: Devoir Surveille 2020 en ligne (discord)

Jeudi 7 Janvier 2021 12h00 à 13h10


Cours de Mme Emad et Mme Boillod-Cerneux

Lien discord :

https://discord.com/channels/780725466868875274/780725649412718602

Le devoir surveillé doit être envoyé à boillod.france@gmail.com à 13h15 AU


PLUS TARD. Tout envoi après 13h15 (heure de réception du mail dans la boîte
mail) sera pénalisé
Prénom :

Nom :

Notations

 Une matrice carrée ou rectangulaire est dénotée par une lettre latine majuscule (A, B, C, etc.)
 Un vecteur est dénoté par une lettre latine minuscule (a, b, c, etc.)
 Un scalaire est dénoté par une lettre grecque minuscule (α, β, etc.)

Exo 1 : Questions de cours:

1. Expliquez les caractéristiques (éléments matériels) d’un superordinateur vectoriel.


2. Qu’est-ce qu’un modèle d’exécution ? Qu’est-ce un modèle de programmation ? citez au
moins deux exemples de chacun.
3. Quelles sont les métriques utilisées pour l’évaluations les performances de codes
numériques sur des (super)ordinateurs parallèles (comme ceux de la liste TOP500) ?
4. Dans un contexte parallèle, comment le travail peut être partagé ? Dans le cas d’une boucle
for (in i=0 ; i<n ; i++), citez deux exemples de partage de travail avec OpenMP : un exemple
utilisant un pragma omp, un autre sans utiliser de pragma omp.
5. Dans quels contexte une synchronisation explicite entre les threads est-elle nécessaire? Citez
un exemple.
6. Parallélisez l’algorithme ci-dessous de manière optimale et justifiez vos propositions

void main(){
int i, n ;
n=4096 ;
double res=0;
double * a, *b, *z, *w ;
//allocation mémoire des variables

For (i =0 ;i<n ; i++){


a[i]+=b[i] ;
}
For (i =0 ;i<n ; i++){
z[i]+=w[i] ;
}

For (i=0 ; i<n ; i++){


res+=a[i]*z[i];
}
}

7. Dans les exemples ci-dessous, donnez les sorties possibles du programme OpenMP. Justifiez
vos reponses

Void foo(){
int i=10;
#pragma omp parallel private(i){
i=i+5
printf(“i=%d\n”, i);
}
}
export OMP_NUM_THREADS = 4
Sortie :

Justification :

Void foo(int i){


i=i+5
printf(“i=%d\n”, i);
}
}

int main() {
int my_tid=0;
#pragma omp parallel
printf(“my_tid=%d\n”, my_tid);
my_tid = omp_get_num_threads();
printf(“my_tid=%d\n”, my_tid);

#pragma omp parallel firstprivate(my_tid)


{
foo(my_tid) ;
}
}

export OMP_NUM_THREADS = 4
Sortie :

Justification :

Exo 2 : Produit Matrice vecteur:

1. Écrivez l’algorithme séquentiel de l’opération y = Ax + βz. On suppose que y est de taille N, A


de taille N*N, z et x de taille N.
2. Donnez sa complexité en temps et en espace.
3. Écrivez l’algorithme parallèle, justifiez vos propositions

Exo 3 : Résolution de système linéaire

// Initialisation aleatoire d'un tableau


void random_number(double* array, int size) {
for(int i=0; i<size; i++) {
array[i] = rand();
}
}

int main() {

int n=2048, diag=4096;


int i, j, iteration=0;
double a[n][n];
double x[n], x_courant[n], b[n];
double norme;

int nb_taches;
#pragma omp parallel
{ nb_taches = omp_get_num_threads(); }

// Initialisation de la matrice et du second membre


#pragma omp 1
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
a [i][j] = rand();
}
}

#pragma omp 2
for(int i=0; i<n; i++) {
b [i] = rand();
}
// Solution initiale
#pragma omp 3
for(int i=0; i<n; i++) {
x[i] = 1.0;
}

// Resolution par la methode de Jacobi


For (int k=0 ; k<n ; k++){

for(int i=0; i<n; i++) {


x_courant[i] = 0;
for(j=0; j<i; j++) {
x_courant[i] += a[j][i]*x[j];
}
for(j=i+1; j<n; j++) {
x_courant[i] += a[j][i]*x[j];
}
x_courant[i] = (b[i] - x_courant[i])/a[i][i];
}
}
}

1. Complétez les pragma omp 1, 2 et 3 de l’algorithme parallèle ci –dessus.


pragma 1
pragma 2
pragma 3

2. On parallélise maintenant la boucle de résolution par la méthode de Jacobi

#pragma omp ????


For (int k=0 ; k<n ; k++){

for(int i=0; i<n; i++) {


x_courant[i] = 0;
for(j=0; j<i; j++) {
x_courant[i] += a[j][i]*x[j];
}
for(j=i+1; j<n; j++) {
x_courant[i] += a[j][i]*x[j];
}
x_courant[i] = (b[i] - x_courant[i])/a[i][i];
}
}
Complétez le pragma omp.

pragma omp

3. On suppose qu’on parallélise la boucle sur i :

#pragma omp 1
For (int k=0 ; k<n ; k++){
#pragma omp 2
for(int i=0; i<n; i++) {
x_courant[i] = 0;
for(j=0; j<i; j++) {
x_courant[i] += a[j][i]*x[j];
}
for(j=i+1; j<n; j++) {
x_courant[i] += a[j][i]*x[j];
}
x_courant[i] = (b[i] - x_courant[i])/a[i][i];
}
}

Complétez les 2 pragmas omp, Justifiez vos propositions

pragma 1
pragma 2

On suppose qu’on parallélise les boucles sur j

#pragma omp 1
For (int k=0 ; k<n ; k++){
for(int i=0; i<n; i++) {
x_courant[i] = 0;
#pragma omp 2
for(j=0; j<i; j++) {
x_courant[i] += a[j][i]*x[j];
}
#pragma omp 3
for(j=i+1; j<n; j++) {
x_courant[i] += a[j][i]*x[j];
}
x_courant[i] = (b[i] - x_courant[i])/a[i][i];
}
}

Complétez les 2 pragmas omp, Justifiez vos propositions

pragma 1
pragma 2
Pragma 3

Exo 4 : Temps d’exécution d’un code OpenMP

Dans cet exercice, nous considérons la fonction foo(int i). La fonction effectue les opérations
suivantes :

void foo (int i, double *x, double *y) {


for (int j =0; j<i*2048; j++){
y[j] = y[j] + 5*x[j]/2.34
}
}

1. Calculez la complexité en espace de la fonction foo, pour i=1 et pour i = 10.


2. On s’intéresse maintenant au code ci-dessous :

void foo (int i, double *x, double *y) {


for (int j =0; j<i*5000000; j++){
y[j] = y[j] + 5*x[j]/2.34
}
}

int main() {

int i=1;
double *x,*y ;
x = malloc(2048) ;
y = malloc(2048) ;

for(int k=0; k<100; k++) {


x[k] = rand();
y[k] = rand();
}
#pragma omp parallel for
for(int i = 1; i<4096; i++) {
foo(i, x, y);
}
free(x); free(y);
}

2.1 On suppose qu’on a 2 threads. Quel thread sera le plus long en terme de temps d’exécution?
Pourquoi ?
2.2 Si on utilise schedule(dynamic,1), quel comportement pourrez-vous observer ?
2.3 Quel mode de schedule serait le plus adéquat ? static, guided ou dynamic ?
Justifiez votre proposition.

Vous aimerez peut-être aussi