Question

Supposons que j'ai un code très simple comme:

double array[SIZE_OF_ARRAY];
double sum = 0.0;

for (int i = 0; i < SIZE_OF_ARRAY; ++i)
{
    sum += array[i];
}

En gros, je veux faire les mêmes opérations à l'aide de SSE2.Comment puis-je le faire?

Était-ce utile?

La solution

Voici un très simple jeu d'instructions SSE3 mise en œuvre:

#include <emmintrin.h>

__m128d vsum = _mm_set1_pd(0.0);
for (int i = 0; i < n; i += 2)
{
    __m128d v = _mm_load_pd(&a[i]);
    vsum = _mm_add_pd(vsum, v);
}
vsum = _mm_hadd_pd(vsum, vsum);
double sum = _mm_cvtsd_f64(vsum0);

Vous pouvez dérouler la boucle pour obtenir de bien meilleures performances à l'aide de plusieurs accumulateurs pour masquer la latence de la PF plus (comme suggéré par @Mysticial).Déroulez 3 ou 4 fois avec de multiples "somme" des vecteurs de goulot d'étranglement de la charge et du FP-ajouter le débit (un ou deux par cycle d'horloge) au lieu de FP-ajouter de la latence (un par 3 ou 4 cycles):

__m128d vsum0 = _mm_setzero_pd();
__m128d vsum1 = _mm_setzero_pd();
for (int i = 0; i < n; i += 4)
{
    __m128d v0 = _mm_load_pd(&a[i]);
    __m128d v1 = _mm_load_pd(&a[i + 2]);
    vsum0 = _mm_add_pd(vsum0, v0);
    vsum1 = _mm_add_pd(vsum1, v1);
}
vsum0 = _mm_add_pd(vsum0, vsum1);    // vertical ops down to one accumulator
vsum0 = _mm_hadd_pd(vsum0, vsum0);   // horizontal add of the single register
double sum = _mm_cvtsd_f64(vsum0);

Notez que le tableau a est supposé être de 16 octets alignés et le nombre d'éléments n est supposé être un multiple de 2 (ou 4, dans le cas du déroulé de la boucle).

Voir aussi Moyen le plus rapide pour faire horizontale float somme vectorielle sur x86 pour d'autres façons de faire la somme horizontale à l'extérieur de la boucle.SSE3 soutien n'est pas totalement universelle (en particulier les Processeurs AMD ont été, plus tard, à l'appui de ce que l'Intel).

Aussi, _mm_hadd_pd n'est généralement pas le moyen le plus rapide, même sur des Processeurs qui prennent en charge, de sorte qu'un SSE2 seule version ne sera pas pire sur les Processeurs modernes.C'est en dehors de la boucle et n'a pas beaucoup de différence de toute façon, si.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top