2010-11-18 3 views
3

Je me demande s'il est possible d'utiliser SSE (1,2,3,4, ...) afin d'optimiser la boucle suivante:Optimisation des différences finies w/SSE

// u and v are allocated through new double[size*size] 
for (int j = l; j < size-1; ++j) 
{ 
    for (int k = 1; k < size-1; ++k) 
    { 
     v[j*size + k] = (u[j*size + k-1] + u[j*size + k+1] 
         + u[(j-1)*size + k]+ u[(j+1)*size + k])/4.0; 
    } 
} 

L'idiome est utilisé [j*size + k] traiter le bloc de mémoire comme s'il s'agissait d'un tableau multidimensionnel.

Malheureusement, l'indicateur -ftree-vectorize pour GCC (4.5) ne croit pas que la boucle peut faire l'objet d'une optimisation de type SIMD. (Bien que je dise n'avoir jamais vu -ftree-vectorize optimiser quoi que ce soit sauf les plus triviales des boucles.)

Bien que je sache qu'il existe de nombreuses autres façons d'améliorer les performances de la boucle (OpenMP, dérouler, algorithmes in-situ) , etc) Je suis particulièrement intéressé de savoir si SIMD peut être utilisé. Je suis peut-être plus intéressé par les grandes lignes de la façon dont une telle boucle pourrait être transformée (si tant est qu'elle le soit), par opposition à une mise en œuvre concrète.

+0

Avez-vous essayé '-ftree-vectorizer-verbose = n'? gcc vous donnera des indices sur les raisons pour lesquelles il a/n'a pas vectorisé. Un à surveiller est que sans le mot-clé 'restrict' il supposera que v peut alias vous qui bloque beaucoup de SSE (au mieux, il fera deux versions dans ce cas et décidera à l'exécution) –

+0

@Ben Jackson - Yep, I utilisé l'option -verbose pour conclure qu'il ne vectorisait pas mon code. J'ai joué avec 'restrict' (en fait' __restrict__' car je suis en C++) mais cela ne faisait aucune différence car GCC était en ligne (et déterminait que 'u' et' v' ne se chevauchaient pas). –

Répondre

0

On dirait que cela devrait être possible, mais puisque (a) vous utilisez des doubles, (b) vous faites très peu de calculs par rapport aux E/S, (c) les processeurs x86-64 les plus modernes ont deux FPU de toute façon, alors vous pouvez ne pas obtenir beaucoup de retour sur votre investissement de codage SIMD.

+0

J'ai utilisé le double principalement par habitude. Je ne suis pas sûr qu'il soit lié aux E/S car sur mon système dual-core avec L2 partagé, j'obtiens une accélération presque linéaire lorsque j'utilise OpenMP. –

+0

@Freddie: le commentaire lié E/S concernait la boucle scalaire ci-dessus - vous n'avez que 3 additions FP et 1 FP multiplier pour 4 charges + 1 magasin - le temps d'exécution peut être dominé par la latence des charges et des magasins , ce qui rend le calcul plus rapide (par exemple via SIMD) peut ne rien vous apporter. –

+0

@Freddie: si votre algorithme peut utiliser des flotteurs plutôt que des doubles sans problèmes de précision numérique ou de stabilité, alors il pourrait être intéressant de considérer SIMD (bien que vous notiez la remarque ci-dessus concernant le calcul v load/stores). –