Même si tu n'as qu'un port SSE_ADD, l'additionneur flottant est un pipeline à 3 étages. Si tu n'as qu'un seul (vecteur d')accumulateur, tu devras attendre deux cycles le temps que la nouvelle valeur de l'accumulateur sorte du pipeline avant de pouvoir la réinjecter dans l'addition suivante.
Il te faut donc au minimum 3 accumulateurs pour pouvoir lancer une addition par cycle.
Pour t'embrouiller encore plus, si tu es sur Haswell, tu peux aussi utiliser le pipeline FMA sur l'autre port pour faire des additions, en ajoutant des multiplications par 1. Le pipeline FMA fait 5 étages, donc il te faut 5 accumulateurs de plus :
Code:
__mm256 * array;
i = 0;
for(whatever; i+=8) {
somme_partielle1 = _mm256_add_ps(somme_partielle1, array[i]);
somme_partielle2 = _mm256_add_ps(somme_partielle2, array[i+1]);
somme_partielle3 = _mm256_add_ps(somme_partielle3, array[i+2]);
somme_partielle4 = _mm256_fmadd_ps(array[i+3], one, somme_partielle4);
somme_partielle5 = _mm256_fmadd_ps(array[i+4], one, somme_partielle5);
somme_partielle6 = _mm256_fmadd_ps(array[i+5], one, somme_partielle6);
somme_partielle7 = _mm256_fmadd_ps(array[i+6], one, somme_partielle7);
somme_partielle8 = _mm256_fmadd_ps(array[i+7], one, somme_partielle8);
}
// Arbre de réduction inter-vecteurs
somme_partielle1 = _mm256_add_ps(somme_partielle1, somme_partielle2);
somme_partielle3 = _mm256_add_ps(somme_partielle3, somme_partielle4);
somme_partielle5 = _mm256_add_ps(somme_partielle6, somme_partielle5);
somme_partielle7 = _mm256_add_ps(somme_partielle8, somme_partielle7);
somme_partielle1 = _mm256_add_ps(somme_partielle1, somme_partielle3);
somme_partielle5 = _mm256_add_ps(somme_partielle7, somme_partielle5);
somme_partielle1 = _mm256_add_ps(somme_partielle1, somme_partielle5);
// Arbre de réduction intra-vecteur
somme_partielle_1 = _mm256_hadd_ps(somme_partielle_1, somme_partielle_1);
somme_partielle_1 = _mm256_hadd_ps(somme_partielle_1, somme_partielle_1);
somme_partielle_1 = _mm256_hadd_ps(somme_partielle_1, somme_partielle_1);
// Résultat dans les 32 bits de poids faible de somme_partielle_1
Là en principe ça déboite, et le code fait 2 additions vectorielles de 8 éléments chacune par cycle. Bon, en réalité comme dit Thamior ta hiérarchie mémoire n'arrivera jamais à te fournir les 2x256 bits par cycle nécéssaires pour nourrir tes unités de calcul...
Sinon, pour évaluer l'utilisation des ports d'exécution AVX sur une petite boucle, y'a qu'à utiliser l'outil d'Intel du même nom.