Optimisations Faustiennes Ralis par Ramzi DARMOUL Encadr par

  • Slides: 22
Download presentation
Optimisations Faustiennes Réalisé par : Ramzi DARMOUL Encadré par : M. Pierre JOUVELOT (CRI)

Optimisations Faustiennes Réalisé par : Ramzi DARMOUL Encadré par : M. Pierre JOUVELOT (CRI) M. Karim BARKATI (CRI) M. Moncef TEMANI (ISI) 20 septembre 2010

Contexte n Optimisation Faustiennes: ü Etude expérimentale ü Sous-projet 5 du projet ANR ASTREE

Contexte n Optimisation Faustiennes: ü Etude expérimentale ü Sous-projet 5 du projet ANR ASTREE ü nature multi-équipe du stage: Ø Equipe FAUST: Pierre JOUVELOT, Karim BARKATI, Yann ORLAREY, Stéphane LETZ… Ø Equipe PIPS: Corinne ANCOURT, François IRIGOIN, Serge GUELTON, Mehdi AMINI… Ø Membres du CRI: Antoniu POP, Laurent DAVERIO, Claire MEDRALA, Samuel BENVENISTE… Nourchène Elleuch Ben Ayed 2/22

Plan 1. Présentation de FAUST 2. Présentation de PIPS 3. Problématique 4. Workflow 5.

Plan 1. Présentation de FAUST 2. Présentation de PIPS 3. Problématique 4. Workflow 5. Transformations de code 6. Résultats de la vectorisation 7. Résultats de la parallélisation 8. Conclusion et perspectives Nourchène Elleuch Ben Ayed 3/22

FAUST (Functional Audio Stream)(1/2) n Langage de traitement de signal audio en temps réel

FAUST (Functional Audio Stream)(1/2) n Langage de traitement de signal audio en temps réel : ü programmation fonctionnelle ü algèbre de bloc-diagramme Syntaxe Priorité Description expression ~ expression 4 Composition récursive expression , expression 3 Composition parallèle expression : expression 2 Composition séquentielle expression <: expression 1 Composition de division expression : > expression 1 Composition de regroupement n Compilateur qui génère du C++ ü choix d’architectures de déploiement ü calcul DSP au niveau des échantillons Nourchène Elleuch Ben Ayed 4/22

FAUST (Functional Audio Stream)(2/2) noise. dsp random = +(12345) ~ *(1103515245); noise = random

FAUST (Functional Audio Stream)(2/2) noise. dsp random = +(12345) ~ *(1103515245); noise = random /2147483647. 0; process = noise * vslider("noise[style: knob ]", 0, 0, 100, 0. 1)/100; noise. cpp Fonctions GTK, JACK, etc. … class mydsp : public dsp{ … // fonction de DSP void compute(int count, FAUSTFLOAT** input, FAUSTFLOAT** output) { float f. Slow 0 = (4. 656613 e-10 f * fslider 0); FAUSTFLOAT* output 0 = output[0]; for (int i=0; i<count; i++) { i. Rec 0[0] = (12345+(1103515245* i. Rec 0[1])); output 0[i]=(FAUSTFLOAT)(f. Slow 0* i. Rec 0[0]); i. Rec 0[1] = i. Rec 0[0]; } } }; Nourchène Elleuch Ben Ayed 5/22

PIPS (Paralléliseur interprocédural de programmes scientifiques) n Compilateur source-à-source : ü analyses sémantiques ü

PIPS (Paralléliseur interprocédural de programmes scientifiques) n Compilateur source-à-source : ü analyses sémantiques ü optimisations de code ü parallélisation automatique Script TPIPS Source C ou FORTRAN PIPS Source Transformé 6/22

Problématique Nourchène Elleuch Ben Ayed 7/22

Problématique Nourchène Elleuch Ben Ayed 7/22

Workflow Nourchène Elleuch Ben Ayed 8/22

Workflow Nourchène Elleuch Ben Ayed 8/22

Réponses impulsionnelles freeverb. dsp freeverb = vgroup("Freeverb", fxctrl(fixedgain, wet. Slider, stereo. Reverb(combfeed, allpassfeed, damp.

Réponses impulsionnelles freeverb. dsp freeverb = vgroup("Freeverb", fxctrl(fixedgain, wet. Slider, stereo. Reverb(combfeed, allpassfeed, damp. Slider, stereospread))); freeverb. cpp . . . virtual int get. Num. Inputs() { return 2; } virtual int get. Num. Outputs() { return 2; }. . . process = freeverb; freeverb = vgroup("Freeverb", fxctrl(fixedgain, wet. Slider, stereo. Reverb(combfeed, allpassfeed, damp. Slider, stereospread))); process = 1 -1' <: freeverb; Freeverb-impulse. dsp . . . virtual int get. Num. Inputs() { return 0; } virtual int get. Num. Outputs() { return 2; }. . . Freeverb-impulse. cpp Nourchène Elleuch Ben Ayed 9/22

Transformations de code (1/2) int f. Rec 0[3]; int f. Rec 1[2]; int IOTA;

Transformations de code (1/2) int f. Rec 0[3]; int f. Rec 1[2]; int IOTA; . . . void compute (int count, FAUSTFLOAT** input, FAUSTFLOAT** output) { FAUSTFLOAT* output 0 = output[0]; for (int i=0; i<count; i++) {. . . f. Rec 0[0] = f. Vec 1[IOTA-i. Slow 4&511]* f. Rec 0[1] * f. Rec 0[2]; f. Rec 1[0] = (f. Temp 0 - floorf(f. Temp 0)); output 0[i] = (FAUSTFLOAT)ftbl 0[int((65536. 0 f * f. Rec 1[0]))]; // post processing f. Rec 0[2]=f. Rec 0[1]; f. Rec 0[1]=f. Rec 0[0]; f. Rec 1[1] = f. Rec 1[0]; . . . IOTA = IOTA+1; . . . } } Nourchène Elleuch Ben Ayed 10/22

Transformations de code (2/2) float floorf(float x) {. . . } void compute (int

Transformations de code (2/2) float floorf(float x) {. . . } void compute (int count, FAUSTFLOAT input[0][0], FAUSTFLOAT output[1][1024]) { FAUSTFLOAT output 0[1024]; int get. Num. Inputs() int i; { return 0; } int _iota=0; int get. Num. Outputs() int __scalar__0, __scalar__1; . . . ; { return 1; } for (i=0; i<count; i++) { output 0[i]=output[0][i]; } for (i=0; i<count; i++) {. . . __scalar__0= f. Vec 1[_iota-i. Slow 4&511]* __scalar__1* __scalar__2; __scalar__3 = (f. Temp 0 - floorf(f. Temp 0)); output 0[i] = (FAUSTFLOAT)ftbl 0[(int)((65536. 0 f* __scalar__3))]; output[0][i]=output 0[i]; // post processing __scalar__2=__scalar__1; __scalar__1=__scalar__0; __scalar__4=__scalar__3; _iota = i+1; . . . Nourchène Elleuch Ben Ayed 11/22 }

Vectorisation de SAC void compute(int count, float input[0][0], float output[1][256]) {. . . //

Vectorisation de SAC void compute(int count, float input[0][0], float output[1][256]) {. . . // PIPS generated variable float F_03; // PIPS : SAC generated variable int aligned 0[3+1] = {0, 0, 0, 0}, aligned 1[3+1] = {0, 0, 0, 0}; // PIPS : SAC generated double vector(s) __m 128 v 2 df_vec 1; . . . // PIPS SIMD_COMMENT_1 F_03 = f. Slow 2 -f. Vec 0[1]; v 2 df_vec 1=_mm_loadu_ps(F_03); v 2 di_vec 3=_mm_cmpgt_ps(v 2 df_vec 4, v 2 sf_vec 5); v 2 di_vec 3=_mm_storeu_ps(aligned 3[0]); SIMD_MULPD(vec 18, vec 19, vec 20); SIMD_STORE_V 2 DF_TO_V 2 SF(vec 18, &aligned 6[0]); SIMD_ADDPS(vec 21, vec 22, vec 23); . . . } Nourchène Elleuch Ben Ayed 12/22

Validation des transformations de PIPS Nourchène Elleuch Ben Ayed 13/22

Validation des transformations de PIPS Nourchène Elleuch Ben Ayed 13/22

Résultats de vectorisation (1/4) Nourchène Elleuch Ben Ayed 14/22

Résultats de vectorisation (1/4) Nourchène Elleuch Ben Ayed 14/22

Résultats de vectorisation (2/4) Nombre total de défauts dans le cache de données L

Résultats de vectorisation (2/4) Nombre total de défauts dans le cache de données L 1 Nourchène Elleuch Ben Ayed 15/22

Résultats de vectorisation-FAUST (3/4) // boucles non vectorisées avec GCC après pré-vectorisation de FAUST

Résultats de vectorisation-FAUST (3/4) // boucles non vectorisées avec GCC après pré-vectorisation de FAUST // LOOP 0 x 1 d 46270 for (int i=0; i<4; i++) {f. Rec 7_tmp[i]=f. Rec 7_perm[i]; } for (int i=0; i<count; i++) { f. Rec 7[i] = (0 - (((f. Rec 3[i] * f. Rec 7[i-2]) + (f. Rec 2[i] * f. Rec 7[i-1])) - ((float)input 4[i] *f. Rec 1[i]))); } for (int i=0; i<4; i++) {f. Rec 7_perm[i]=f. Rec 7_tmp[count+i]; } // LOOP 0 x 1 d 493 b 0 for (int i=0; i<4; i++) {f. Rec 9_tmp[i]=f. Rec 9_perm[i]; } for (int i=0; i<count; i++) { f. Rec 9[i] = (0 - (((f. Rec 3[i] * f. Rec 9[i-2]) + (f. Rec 2[i] * f. Rec 9[i-1])) ((float)input 6[i] * f. Rec 1[i]))); } // boucles vectorisées avec GCC après pré-vectorisation de FAUST for (int i=0; i<count; i++) { output 0[i] = (FAUSTFLOAT)(f. Rec 0[i] - f. Rec 0[i-1]); } for (int i=0; i<count; i++) { output 1[i] = (FAUSTFLOAT)(f. Rec 4[i] - f. Rec 4[i-1]); } Nourchène Elleuch Ben Ayed 16/22

Résultats de vectorisation-PIPS (4/4) SIMD_STORE_V 4 SF(vec 21, &aligned 7[0]); SIMD_ADDPS(vec 24, vec 25,

Résultats de vectorisation-PIPS (4/4) SIMD_STORE_V 4 SF(vec 21, &aligned 7[0]); SIMD_ADDPS(vec 24, vec 25, vec 26); SIMD_ADDPD(vec 27, vec 4, vec 29); SIMD_STORE_GENERIC_V 2 DF(vec 27, &f. Rec 1[2+LU_IND 0], &f. Rec 2[2+LU_IND 0]); aligned 9[1] = (float) input 0[1+LU_IND 0]*f. Rec 1[1+LU_IND 0]; SIMD_LOAD_V 4 SF(vec 32, &aligned 9[0]); SIMD_SUBPS(vec 30, vec 21, vec 32); SIMD_LOAD_V 4 SF(vec 35, &aligned 11[0]); SIMD_SUBPS(vec 33, vec 24, vec 35); SIMD_UMINPS(vec 36, vec 30); SIMD_STORE_GENERIC_V 4 SF(vec 36, &f. Rec 10[1+LU_IND 0], &f. Rec 4[1+LU_IND 0], &f. Rec 5[1+LU_IND 0]); SIMD_UMINPS(vec 38, vec 33); SIMD_STORE_GENERIC_V 4 SF(vec 38, &f. Rec 6[1+LU_IND 0], &f. Rec 7[1+LU_IND 0], &f. Rec 8[0], &f. Rec 9[1+LU_IND 0]); // Boucles non vectorisées avec PIPS !!! output 0[1+LU_IND 0] = (float) (f. Rec 0[1+LU_IND 0]-f. Rec 0[LU_IND 0]); . . . output 1[1+LU_IND 0] = (float) (f. Rec 4[1+LU_IND 0]-f. Rec 4[LU_IND 0]); Nourchène Elleuch Ben Ayed 17/22

Résultats de parallélisation-PIPS (1/3) #pragma omp parallel for (int i=0; i<4; i++) f. Xec

Résultats de parallélisation-PIPS (1/3) #pragma omp parallel for (int i=0; i<4; i++) f. Xec 0_tmp[i]=f. Xec 0_perm[i]; #pragma omp parallel for (int i=0; i<count; i++) { f. Xec 0[i] = fbutton 0; } #pragma omp parallel for (int i=0; i<4; i++) f. Xec 0_perm[i]=f. Xec 0_tmp[count+i]; #pragma omp parallel for (int i=0; i<4; i++) f. Rec 1_tmp[i]=f. Rec 1_perm[i]; // exec code for (int i=0; i<count; i++) { f. Rec 1[i] = ((((f. Xec 0[i] - f. Xec 0[i-1]) > 0. 0 f) + f. Rec 1[i-1]) - (f. Slow 1 * (f. Rec 1[i-1] > 0. 0 f))); } Nourchène Elleuch Ben Ayed 18/22

Résultats de parallélisation (2/3) Nourchène Elleuch Ben Ayed 19/22

Résultats de parallélisation (2/3) Nourchène Elleuch Ben Ayed 19/22

Résultats de parallélisation-FAUST (3/3) #pragma omp parallel firstprivate(f. Slow 0, f. Slow 1, f.

Résultats de parallélisation-FAUST (3/3) #pragma omp parallel firstprivate(f. Slow 0, f. Slow 1, f. Xec 0, f. Rec 1, i. Rec 2, f. Slow 2, i. Slow 3, f. Rec 0) { for (int index = 0; index < fullcount; index += 32) { // SECTION : 1 #pragma omp single { // LOOP 0 xa 08 de 20 for (int i=0; i<4; i++) f. Xec 0_tmp[i]=f. Xec 0_perm[i]; for (int i=0; i<count; i++) f. Xec 0[i] = fbutton 0; for (int i=0; i<4; i++) f. Xec 0_perm[i]=f. Xec 0_tmp[count+i]; } // SECTION : 2 #pragma omp sections { #pragma omp section { // LOOP 0 xa 08 d 480 for (int i=0; i<4; i++) f. Rec 1_tmp[i]=f. Rec 1_perm[i]; Nourchène Elleuch Ben Ayed 20/22

Conclusion n Difficultés rencontrées : ü le grand nombre d’outils (C, C++ , FAUST,

Conclusion n Difficultés rencontrées : ü le grand nombre d’outils (C, C++ , FAUST, PIPS, jack, qjackctl, alsa, makefile, shell, R, ggplot 2, octave, OProfile, Valgrind, gcc, icc, Open. MP, SSE, emacs, La. Te. X, …) ü certains bugs de PIPS et de SAC n Contributions : ü Vectorisation et parallélisation des exemples DSP de FAUST via PIPS ü Détection de certains bugs dans PIPS ü Comparaison, analyse et interprétation des causes différences de performances ü Propositions d’optimisations FAUST Nourchène Elleuch pour Ben Ayed 21/22

Perspectives n Propositions formulées pour PIPS : ü Etendre la branche Open. MP ü

Perspectives n Propositions formulées pour PIPS : ü Etendre la branche Open. MP ü Stabiliser la branche SAC n Propositions formulées pour FAUST : ü Générer des tableaux au lieu des pointeurs ü Générer du code C ü S’inspirer de l’algorithme de SAC de PIPS pour réaliser une vectorisation automatique ü Combiner le parallélisme de tâches de FAUST avec le parallélisme de données de PIPS Nourchène Elleuch Ben Ayed 22/22