La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Département Informatique L’optimisation Laurent JEANPIERRE IUT de CAEN – Campus 3.

Présentations similaires


Présentation au sujet: "Département Informatique L’optimisation Laurent JEANPIERRE IUT de CAEN – Campus 3."— Transcription de la présentation:

1 Département Informatique L’optimisation Laurent JEANPIERRE IUT de CAEN – Campus 3

2 Département Informatique 2 Contenu du cours Introduction Le Pentium 4 Conseils généraux Optimiser le code assembleur Conseils généraux Conseils spécifiques

3 Département Informatique 3 L’optimisation En théorie ? Rendre un programme optimal ! En pratique ? Augmenter sa vitesse d’exécution Réduire son empreinte mémoire Rarement compatibles…

4 Département Informatique 4 Principes de base Règle fondamentale : D’abord un programme qui marche Ensuite un programme optimisé TESTER après chaque optimisation ! Langages de haut niveau Faciles à utiliser Développement rapide Surcouche importante  Pas optimisé

5 Département Informatique 5 L’optimisation aujourd’hui Un programme classique « optimisé », c’est : 90 % de haut niveau (plusieurs millions lignes) Interface utilisateur, sauvegarde, … Java, SmallTalk, Delphi, C++, … 9 % de bas niveau (100-1000 lignes) Routines souvent utilisées, … Maîtrise nécessaire (processeur, mémoire) Pascal, C, … 1 % d’assembleur (<200 lignes) Routines critiques (temps exécution) Exécutées des millions de fois (boucles)

6 Département Informatique 6 Dans ce cours… Focus sur le Pentium 4 Disponible en salle machine Machines courantes aujourd’hui Principes restent valables Pour d’autres processeurs Pour d’autres compilateurs Dans certaines limites

7 Département Informatique 7 Contenu du cours Introduction Le Pentium 4 Conseils généraux Optimiser le code assembleur Conseils généraux Conseils spécifiques

8 Département Informatique 8 Le Pentium 4 Processeur CISC à cœur RISC Instructions CISC  opérations RISC (  op) Architecture netburst : Pipeline long (30) Architecture super-scalaire Plusieurs unités parallèles Processeur de nouvelle génération Optimise le code à la volée

9 Département Informatique 9 Architecture P4 ( © Intel )

10 Département Informatique 10 Architecture P4 (1) Le cache L2 : 256Ko, données + instructions L1 : 8Ko données 2 cache-miss avant remplissage du cache Accès en ordre croissant uniquement Trace : 12K  op (≈60K ?) Le Front-End (Pré-)charge les instructions Décode les instructions chargées (1/cycle) Cache les  op dans le trace-cache Fournit les  op aux unités de calcul (3/cycle)

11 Département Informatique 11 Architecture P4 (2) Retirement Unit « Mise à la retraite » Finalise les  op Valide les données des registres Dans l’ordre du programme original Voir l’unité d’exécution… Jusqu’à 3  op/cycle

12 Département Informatique 12 Architecture P4 (3) Le prédicateur de branchements Prédit si un saut sera suivi ou non Au moment de son décodage Avant son exécution ! Statique : au décodage Saut Jmp/Call : exécuté Saut en arrière : exécuté Saut en avant : non exécuté Dynamique : si dans le trace-cache Selon les exécutions précédentes Statistiques sommaires... et en nombre limité (4096 pour les sauts, 16 pour les RET )

13 Département Informatique 13 Architecture P4 (4) Unité d’exécution ( © Intel ) 4 ports en parallèle, out of order

14 Département Informatique 14 Architecture P4 (5) Unité d’exécution (2) 4 ports en parallèle : Chaque port est indépendant 1 cycle pour le transfert de données de port à port ≠ Sauf de Load aux autres Chaque port est « pipeliné » Exécution de plusieurs instructions en séquence Granularité variable ½ cycle pour les ALU 2 cycles pour les FPU/SIMD PAS DU TOUT pour les divisions, ni FPU avancé (√,…)

15 Département Informatique 15 Architecture P4 (6) Unité d’exécution (3) Les données en mémoire Port 2 pour le chargement Crée un nouveau registre si besoin Port 3 pour le stockage Mémoire lente… Registres virtuels : Le P3 a 40 registres gen., le P4 en a 120 ! Un Load ou une opération ALU Alloue un registre Permet l’exécution hors-ordre si besoin

16 Département Informatique 16 Architecture P4 (7) Unité d’exécution (4) Utilise des buffers locaux 48 en lecture 24 + en écriture (selon versions) « Store forwarding » : copie de buffer à buffer sans passer par la mémoire ! « Write combining » : écriture de paquets en mémoire (ex. : 1*64 au lieu de 8*8) Store Forwarding, règles du jeu On ne lit pas plus que ce qu’on a écrit On aligne les lectures et les écritures Il faut écrire AVANT de lire

17 Département Informatique 17 Contenu du cours Introduction Le Pentium 4 Conseils généraux Optimiser le code assembleur Conseils généraux Conseils spécifiques

18 Département Informatique 18 Conseils généraux D’abord améliorer les algorithmes Ex. : Quick-sort au lieu du tri à bulles. Utiliser les données les plus petites Si la précision le permet ! float au lieu de double char au lieu de int (éventuellement)  traitement plus rapide  parallélisation possible (SIMD)

19 Département Informatique 19 Conseils généraux (2) Eviter les variables globales Accès relatif (8b ou 16b au lieu de 32b) Meilleure localité (cache + efficace) Eviter les écritures multiples en // Seulement 4 buffers pour le Write- Combining Eviter de jouer avec les pointeurs Préférer les tableaux  Compilation optimisée plus facile

20 Département Informatique 20 Conseils généraux (3) Eviter les branches Le programme se suit naturellement Pas de branchement  pas d’erreur de prédiction « Inliner » les fonctions courtes (évite bouger pile) Aligner variables Accès plus rapide Accès séquentiel  cache optimisé

21 Département Informatique 21 Conseils généraux (4) Eviter les dépendances longues Autoriser le parallélisme Exemple : eax  v1*v2*v3*v4*v5*v6*v7*v8 movlv1,%eax #1 imullv2,%eax #14/8 imullv3,%eax #14/8 imullv4,%eax #14/8 imullv5,%eax #14/8 imullv6,%eax #14/8 imullv7,%eax #14/8 imullv8,%eax #14/8  1+7*14=99 cycles movlv1,%eax #1#0-1 imullv2,%eax #14/8#1-15 (0) movlv3,%ebx #1 #2-3 imullv4,%ebx #14/8#3-17 (1) movlv5,%ecx #1 #4-5 imullv6,%ecx #14/8#9-23 (0) movlv7,%edx #1 #5-6 imullv8,%edx #14/8#11-25(1) imull%ebx,%eax #14/4.5#17-31(0) imull%ecx,%edx #14/4.5#25-39(1) mov$0,%edx #0.5#6-7 !!!!  39 cycles

22 Département Informatique 22 Contenu du cours Introduction Le Pentium 4 Conseils généraux Optimiser le code assembleur Conseils généraux Conseils spécifiques

23 Département Informatique 23 Optimiser le code assembleur… Soit écrire le code de toute pièce Soit optimiser le travail fait par un compilateur Souvent spécifique à un processeur particulier… Tout à refaire si le programme change !

24 Département Informatique 24 Contenu du cours Introduction Le Pentium 4 Conseils généraux Optimiser le code assembleur Conseils généraux Conseils spécifiques

25 Département Informatique 25 Conseils généraux Préférer les instructions simples Consulter les tables du fabricant Ex : LOOP : 8 cycles (+ besoin ROM microcode) SUB $-1 + JNZ : 1+1  ops, 1 cycle ! IMUL $3 : 14 cycles (+ besoin ROM microcode) 3*ADD : 1.5 cycles ! Eviter registres xH Crée de fausses dépendances Impose 1  op de plus (Shift interne) Eviter les instructions INC/DEC Drapeau C intouché  Crée dépendance

26 Département Informatique 26 Conseils généraux (2) Passer les paramètres par registre Evite le stockage en mémoire Dérouler boucles (quoique ?) ≤ 16 itérations  prédiction de branchement meilleure Sauf si taille  > Trace-cache ! Utiliser LEA pour calculs simples Sauf échelle (trop lent) Ex : LEA 15(%ebx,%ecx),%eax  eax  ebx+ecx+15 Utiliser XOR au lieu de MOV $0 Plus rapide, code plus court Casse la dépendance aussi (SAUF XORP !)

27 Département Informatique 27 Conseils généraux (3) Ne pas mélanger code et données  Panique du cache Aligner les sauts sur 16 octets Surtout pour le Pentium-M Ne pas créer le cadre pile si inutile Récupère registre EBP Instructions en moins Placer les invariants en mémoire Libère un registre Efficace grâce au cache + load-buffer

28 Département Informatique 28 Contenu du cours Introduction Le Pentium 4 Conseils généraux Optimiser le code assembleur Conseils généraux Conseils spécifiques

29 Département Informatique 29 Conseils spécifiques Préférer le SSE2 aux FPU Si beaucoup de calculs Plus rapide (même unité de calcul) Possibilité de traitement parallèle Sauf si instructions spécifiques (trigo, …)

30 Département Informatique 30 Conseils spécifiques SSE : Aligner les données Accès mémoire plus rapide si @=16x  Ajouter du bourrage ! Plusieurs tableaux  tableau de structure  Parallélisation plus simple FPU : Opérations avec des entiers 16b (PAS 32b) Préférable de charger l’entier + opération flottante

31 Département Informatique 31 Exemple: Rotation 2D en C Algorithme intuitif #define N 4096 #define A M_PI/4. struct point {double x,y;}; struct point pts[N]={{1,1},{-1,1}, {-1,-1},{1,-1}}; struct point res[N]; int main() { int i,j; double ca = cos(A); double sa = sin(A); for (j=0;j<500000;j++) // Pour mesurer des choses for (i=0; i<N; i++) { res[i].x = pts[i].x*ca – pts[i].y*sa; res[i].y = pts[i].x*sa + pts[i].y*ca; }// for i } Normal : 21s Optimisé O3:12s

32 Département Informatique 32 Exemple: Rotation 2D en C Sans les structures #define N 4096 #define A M_PI/4. double px[N]={1,-1,-1,1}; double py[N]={1,1,-1,-1}; double rx[N]={1,-1,-1,1}; Double ry[N]={1,1,-1,-1}; int main() { int i,j; double ca = cos(A); double sa = sin(A); for (j=0;j<500000;j++) // Pour mesurer des choses for (i=0; i<N; i++) { rx[i] = px[i]*ca – py[i]*sa; ry[i] = px[i]*sa + py[i]*ca; }// for i } Normal : 14s Optimisé O3:9s

33 Département Informatique 33 Exemple: Rotation 2D en C Algorithme intuitif, double  float #define N 4096 #define A M_PI/4. struct point {float x,y;}; struct point pts[N]={{1,1},{-1,1}, {-1,-1},{1,-1}}; struct point res[N]; int main() { int i,j; float ca = cos(A); float sa = sin(A); for (j=0;j<500000;j++) // Pour mesurer des choses for (i=0; i<N; i++) { res[i].x = pts[i].x*ca – pts[i].y*sa; res[i].y = pts[i].x*sa + pts[i].y*ca; }// for i } Normal : 14s Optimisé O3:9s

34 Département Informatique 34 Exemple: Rotation 2D en C Sans structure, double  float #define N 4096 #define A M_PI/4. float px[N]={1,-1,-1,1}; float py[N]={1,1,-1,-1}; float rx[N]={1,-1,-1,1}; float ry[N]={1,1,-1,-1}; int main() { int i,j; float ca = cos(A); float sa = sin(A); for (j=0;j<500000;j++) // Pour mesurer des choses for (i=0; i<N; i++) { rx[i] = px[i]*ca – py[i]*sa; ry[i] = px[i]*sa + py[i]*ca; }// for i } Normal : 14s Optimisé O3:9s

35 Département Informatique 35 Exemple: Rotation 2D en SSE Algorithme intuitif.data.align 16 N=1024 px:.rept N.double 1,-1,-1,1.endr py:.rept N.double 1,1,-1,-1.endr rx:.space 8*4*N ry:.space 8*4*N ca:.double 0,0 sa:.double 0,0 format:.string "%f, %f\n" Quatre:.short 4 off=py-px.text.global main main: pushl %ebp fldpi fidivsQuatre fsincos fstlca fstplca+8 fstlsa fstplsa+8 movapsca,%xmm4 movapssa,%xmm5

36 Département Informatique 36 Exemple: Rotation 2D en SSE Algorithme intuitif (suite) movl$500000,%ebx boucle3: movl$(2*N),%ecx movl$px,%esi movl$rx,%edi boucle: movapd(%esi),%xmm0 movapdoff(%esi),%xmm1 movapd(%esi),%xmm2 movapdoff(%esi),%xmm3 mulpd%xmm5,%xmm0# x.sin a mulpd%xmm5,%xmm1# y.sin a mulpd%xmm4,%xmm2# x.cos a mulpd%xmm4,%xmm3# y.cos a subpd%xmm1,%xmm2 addpd%xmm0,%xmm3 movapd%xmm2,(%edi) movapd%xmm3,off(%edi) addl$16,%esi addl$16,%edi loopboucle subl$1,%ebx jnzboucle3 Temps : 4,9s

37 Département Informatique 37 Exemple: Rotation 2D en SSE Algorithme optimisé (cœur – 1) movl$500000,%ebx movl$(-32*N),%ecx.align16 boucle3: boucle: movapdrx(%ecx),%xmm1# 1u port 2, 7/10-7 movapdpy(%ecx),%xmm0# 1u port 2, 7/11-8 movapdpy(%ecx),%xmm2# 1u port 2, 7/12-9 movapdrx(%ecx),%xmm3# 1u port 2, 7/13-10 movapdpy+16(%ecx),%xmm4# 1u port 2, 7/14-11 movapdrx+16(%ecx),%xmm5# 1u port 2, 7/15-12 movapdpy+16(%ecx),%xmm6# 1u port 2, 7/16-13 mulpdsa,%xmm1 # y.sin a# 1u port 1, 7/2+17-14 movapdrx+16(%ecx),%xmm7# 1u port 2, 7/18-15 mulpdca,%xmm2 # x.cos a# 1u port 1, 7/2+19-16 mulpdsa,%xmm0 # x.sin a# 1u port 1, 7/2+111-18 mulpdca,%xmm3 # y.cos a# 1u port 1, 7/2+113-20

38 Département Informatique 38 Exemple: Rotation 2D en SSE Algorithme optimisé (cœur – 2) movapd%xmm2,ry(%ecx)# 2u port 0, 7/222-29 movapd%xmm3,ca(%ecx)# 2u port 0, 7/225-31 subpd%xmm5,%xmm6# rx# 1u port 1, 4/2+126-30 addpd%xmm4,%xmm7# ry# 1u port 1, 4/2+128-32 movapd%xmm6,ry+16(%ecx)# 2u port 0, 7/231-38 movapd%xmm7,ca+16(%ecx)# 2u port 0, 7/233-40 nop# 1u port 0/1, 0.532-32.5 addl$32,%ecx# 1u port 0/1, 0.534-34.5 #----- # 30u jnzboucle# 1u port 0, ?/0.534.5-35 nop# 1u port 0/1, 0.535-35.5 nop# 1u port 0/1, 0.535.5-36 movl$(-32*N),%ecx# 1u port 0/1, 0.536-36.5 subl$1,%ebx# 1u port 0/1, 0.5/0.5 +0.5 jnzboucle3# 1u port 0(branch), ?/0.5

39 Département Informatique 39 Exemple: Rotation 2D en SSE Algorithme optimisé (cœur – 3) jnzboucle# 1u port 0, ?/0.5 nop# 1u port 0/1, 0.5 movl$(-32*N),%ecx# 1u port 0/1, 0.5 subl$1,%ebx# 1u port 0/1, 0.5 jnzboucle3# 1u port 0, ?/0.5 #---- # 6u Temps : 4,5s XMM0XMM3XMM1XMM2XMM4XMM7XMM5XMM6 x0|x1y0|y1 x0|x1x1|x2y1|y2 x1|x2 *sin*cos*sin*cos*sin*cos*sin*cos +-+- ry0|ry1rx0|rx1ry1|ry2rx1|rx2

40 Département Informatique 40 Exemple: Rotation 2D en SSE Algorithme optimisé floats Chaque registre contient 4 float ou 2 double  Meilleur parallélisme ! ca contient 4 fois le cosinus sa contient 4 fois le sinus Temps : 2,25s XMM0XMM3XMM1XMM2XMM4XMM7XMM5XMM6 x0..x3y0..y3 x0...x3x4..x7y4..y7 x4..x7 *sin*cos*sin*cos*sin*cos*sin*cos +-+- ry0..ry3rx0..rx3ry4..ry7rx4..rx7

41 Département Informatique 41 Bilan & Conclusion Le programme optimisé est Plus rapide (14 secondes  2,25 secondes) Plus long (31 lignes de C  120 lignes d’asm.) Ecriture du programme C 1 heure Ecriture du programme Assembleur 3-4 heures Optimisation du programme Plusieurs dizaines d’heures Mais un programmeur expérimenté irait plus vite… certainement…


Télécharger ppt "Département Informatique L’optimisation Laurent JEANPIERRE IUT de CAEN – Campus 3."

Présentations similaires


Annonces Google