comment utiliser la fonction de comparaison de tableau de vectorisation automatique

Ceci est une suite à ce post . Clause de non-responsabilité: Je n’ai effectué aucun profilage et je n’ai même pas d’application. C’est uniquement pour moi d’apprendre davantage sur la vectorisation.

Mon code est ci-dessous. Je comstack avec gcc 4.9.4 sur une machine avec un i3 m370. La première boucle vectorise comme je l’attendais. Cependant, la seconde boucle vérifiant chaque élément de temp n’est pas AFAICT vectorisée, avec toutes les instructions “andb”. Je m’attendais à ce qu’il soit vectorisé avec quelque chose comme _mm_test_all_ones . Comment cette boucle peut-elle aussi être vectorisée? Deuxième question, je veux vraiment que cela fasse partie d’une boucle plus grande. Si je dégage le commentaire ci-dessous, rien ne se vectorise. Comment puis-je aussi obtenir que vectorisé?

#define ARR_LENGTH 4096 #define block_size 4 typedef float afloat __atsortingbute__ ((__aligned__(16))); char all_equal_2(afloat *a, afloat *b){ unsigned int i, j; char r = 1; unsigned int temp[block_size] __atsortingbute__((aligned(16))); //for (i=0; i<ARR_LENGTH; i+=block_size){ for (j = 0; j < block_size; ++j) { temp[j] = (*a) == (*b); a++; b++; } for (j=0; j<block_size; j++){ r &= temp[j]; } /*if (r == 0){ break; } }*/ return r; } 

Et la section clé de l’assemblage résultant:

 .cfi_startproc movaps (%rdi), %xmm0 cmpeqps (%rsi), %xmm0 movdqa .LC0(%rip), %xmm1 pand %xmm0, %xmm1 movaps %xmm1, -24(%rsp) movl -24(%rsp), %eax andl $1, %eax andb -20(%rsp), %al andb -16(%rsp), %al andb -12(%rsp), %al ret .cfi_endproc 

Mise à jour: Ce message est similaire à ma première question. Dans cette question, le vecteur était un pointeur brut, de sorte que les erreurs de segmentation sont possibles, mais ce n’est pas un problème. Par conséquent, autant que je sache, la réorganisation des opérations de comparaison est sûre ici, mais pas là. La conclusion est probablement la même si.

Votre boucle est donc petite et récursive: le résultat de l’itération N est utilisé comme entrée de l’itération N + 1. Si vous modifiez votre deuxième boucle pour autoriser 2 opérations par partition:

  char r2 = r; for (j=0; j 

vous verrez que la sortie est optimisée

 .cfi_def_cfa_register %rbp vmovss (%rdi), %xmm0 ## xmm0 = mem[0],zero,zero,zero vmovss 4(%rdi), %xmm1 ## xmm1 = mem[0],zero,zero,zero vucomiss (%rsi), %xmm0 sete %al vucomiss 4(%rsi), %xmm1 sete %cl andb %al, %cl movzbl %cl, %eax popq %rbp retq .cfi_endproc 

pour le dernier point, avec le code optimisé et la boucle externe activée, je vois quelques optimisations. Avez-vous changé les options de compilation?

L’autovectorisation aime beaucoup les opérations de réduction. L’astuce consistait donc à en faire une réduction.

 #define ARR_LENGTH 4096 typedef float afloat __atsortingbute__ ((__aligned__(16))); int foo(afloat *a, afloat *b){ unsigned int i, j; unsigned int result; unsigned int blocksize = 4; for (i=0; i 

Comstack dans une belle boucle:

 .L3: movaps (%rdi,%rax), %xmm1 addl $1, %ecx cmpeqps (%rsi,%rax), %xmm1 addq $16, %rax cmpl %r8d, %ecx psubd %xmm1, %xmm0 jb .L3