Mineure HPC & Support au Big Data
Cours de 3ème année à Supélec

BE d'optimisations sérielles, de vectorisation et de multithreading par OpenMP

(Utilisation optimale d'un noeud de calcul)

Stéphane Vialle

Exercice 1 : optimisations sérielles manuelles et progressives d'un produit de matrices en C sous Linux/gcc

Certaines optimisation sont réalisées par les compilateurs, d’autres nécessitent une modification du code source par le programmeur. Chaque optimisation explicite est liée à un concept d’architecture, et équivaut à prendre en compte l’architecture de la machine depuis le code source. Cependant, la plupart de ces optimisations sont « standard » et sont valables sur la majorité des systèmes. 

Dans cet exercice :

1.1 - Prenez connaissance du code 

1.2 - Réalisez une première mesure de performances sur le kernel 0

1.3 - Optimisation du kernel 0

Conservez vos versions intermédaires !!
Utilisation de l'option -Ox (avec x variant de 0 à 3) en modifiant le Makefile.
Compilez encore votre programme avec des matrices de 1024x1024.
Modifiez votre code source pour utiliser un "accumulateur local" et accéder moins souvent au tableau C.
Vérifiez l'exactitude des résultats.
Puis mesurez les performances obtenues en -O0 et en -O3

Ensuite restez en -O3
Identifiez où se situent (théoriquement) des défauts de cache fréquents dans ce programme (si le temps le permettait on utiliserait un profiler de code, comme Valgrind).

Evitez les défauts de cache en réorganisant les structures de données (et sans changer l’ordre naturel des instructions).
Vérifiez l'exactitude des résultats, puis mesurez les performances obtenues

Si les temps d'exécution deviennent trop faible (juste quelques secondes) compilez votre programme avec des matrices de 2048x2048.
      Quelles sont les options de compilation agissant sur le « loop unrolling » (étudiez le « man » de gcc) ?
      Compilez et testez avec chaque option de compilation de "loop unrolling", sans modifier votre code source.

      Déroulez explicitement la (bonne) boucle d'un facteur 4, puis 8 (puis 16), compilez sans option de "loop unrolling" et testez.

      Modifiez votre code (comme précédemment) ET compilez avec l'option de "loop unrolling" adaptée à votre programme, et testez.
      Rmq :  On peut aussi "guider le compilateur" pour qu'il l'enclenche plus facilement (mais l'utilisation du compilateur icc d'Intel n'est pas prévue dans ces BEs).
      Revenez au code initial, et changez l'ordre des boucles de calcul pour diminuer les défauts de cache et favoriser la vectorisation (compilez toujours en -O3)

      1.4 - Finalisation des expérimentations :

      Il est préférable de tracer les accélérations obtenues sur des séries de mesures homogènes (même taille de matrices).
      Ré-exécutez les premières versions peu optimisées du code sur une matrice de 2048x2048, pour avoir une série de mesures homogènes.

      1.5 - Bilan des optimisations :