2016-06-04 4 views
0

Depuis que je me suis perdu à travers toute la lecture de SIMD et OpenMP en fonction de la vectorisation, je voudrais vous demander si quelqu'un peut me clarifier ce qui précède. Plus précisément, j'ai une partie d'un code C++ que je veux paralléliser, mais je suis assez bourré pour le moment et je ne peux pas trouver quelque chose par moi-même. Toute aide pour m'expliquer ce qu'est exactement la vectorisation et comment l'utiliser dans la partie suivante du code serait grandement appréciée!Vectorisation & #pragma omp simd

for(unsigned short i=1; i<=N_a; i++) { 
     for(unsigned short j=1; j<=N_b; j++) { 
      temp[0] = H[i-1][j-1]+similarity_score(seq_a[i-1],seq_b[j-1]); 
      temp[1] = H[i-1][j]-delta; 
      temp[2] = H[i][j-1]-delta; 
      temp[3] = 0.; 
      H[i][j] = find_array_max(temp, 4); 
      switch(ind) { 
      case 0:         // score in (i,j) stems from a match/mismatch 
       I_i[i][j] = i-1; 
       I_j[i][j] = j-1; 
       break; 
      case 1:         // score in (i,j) stems from a deletion in sequence A 
       I_i[i][j] = i-1; 
       I_j[i][j] = j; 
       break; 
      case 2:         // score in (i,j) stems from a deletion in sequence B 
       I_i[i][j] = i; 
       I_j[i][j] = j-1; 
       break; 
      case 3:         // (i,j) is the beginning of a subsequence 
       I_i[i][j] = i; 
       I_j[i][j] = j; 
       break; 
      } 
     } 
    } 

Cordialement!

+0

SIMD sur x86 est tout au sujet du chargement 16B (ou 32B) de données contiguës, et faire par exemple quatre 'float'' add's en parallèle, ou deux 'double', ou des entiers de différentes largeurs. Ou shuffling/blending/packed-compare pour obtenir un blend-mask/... –

+0

'H [i] [j]' en fonction de 'H [i-1] [j-1]', 'H [ii] [ j] 'et' H [i] [j-1] ', il n'y a pas de moyen direct de vectoriser ou de paralléliser les boucles dans' i' ou 'j'. Eh bien, vous pouvez probablement faire en sorte que le compilateur vectorise et/ou les parallélise en utilisant '#pragma omp simd' et' #pragma omp parallel for', mais le résultat calculé sera faux. – Gilles

Répondre

1

Donc ind est constant pour les deux boucles imbriquées?

Vous pourriez obtenir un compilateur pour auto-vectoriser cela pour vous avec OpenMP. (Mettre la ligne #pragma omp simd juste avant l'une de vos boucles for, et voir si cela affecte le asm lorsque vous compilez avec -O3. Je ne sais pas OpenMP que, donc IDK si vous avez besoin d'autres options.)

Enveloppez dans une fonction qui compile réellement, donc je peux voir ce qui se passe. (par exemple en mettant le code sur http://gcc.godbolt.org/ pour obtenir une sortie asm bien formatée). Si elle ne s'auto-vectorise pas, il n'est probablement pas trop difficile à vectoriser manuellement avec Intel intrinsics pour x86, puisque vous initialisez juste des tableaux avec l'index de tableau. Gardez un vecteur de compteurs de boucle commençant par un vecteur de __m128i jvec = _mm_set_epi32(3, 2, 1, 0); et incrémenter avec _mm_add_ps() avec un vecteur de [ 4 4 4 4 ] (_mm_set1_epi32(4)) pour incrémenter chaque élément par 4.

Gardez un vecteur distinct i valeurs, que vous modifiez seulement la boucle externe, mais toujours stocker dans la boucle interne.


Voir le wiki tag pour des trucs jeu d'instructions.

Voir le wiki tag pour certains guides SIMD, y compris cette belle intro to SIMD and what it's all about.

+0

Mais comment puis-je savoir que la sortie est vectorisée correctement et sans aucune dépendance? – Diaman

+0

@MrDiaman: En regardant la sortie asm. Ou selon le compilateur, il y a des options à signaler sur le succès/l'échec de l'autovectorisation. De quel genre de dépendances vous inquiétez-vous? –

+0

J'ai besoin de l'exactitude sur les données. Nous parlons donc de dépendances de données. Je ne sais pas combien cela peut aider, par ici https://github.com/MrDiaman/Proj/pull/1/files – Diaman