3 votes

Activer arch:SSE2 rend le programme plus lent

Sur Visual Studio 2010, lorsque j'active les ensembles d'instructions améliorés sur le code suivant, le temps d'exécution augmente en réalité.

void add(float * input1, float * input2, float * output, int size)
{
    for(int iter = 0; iter < size; iter++)
    {
        output[iter] = input1[iter] * input2[iter];
    }
}

int main()
{

    const int SIZE = 10000000;
    float *in1 = new float[SIZE];
    float *in2 = new float[SIZE];
    float *out = new float[SIZE];
    for(int iter = 0; iter < SIZE; iter++)
    {
        in1[iter] = std::rand();
        in2[iter] = std::rand();
        out[iter] = std::rand();
    }
    clock_t start = clock();
    for(int iter = 0; iter < 100; iter++)
    {
        add(in1, in2, out, SIZE);
    }
    clock_t end = clock();
    double time = difftime(end,start)/(double)CLOCKS_PER_SEC;

    system("PAUSE");
    return 0;
}

Je reçois systématiquement environ 2.0 secondes pour la variable time avec SSE2 activé, mais environ 1.7 secondes lorsqu'il est "Non défini". Je construis sur Windows 7 64bits, VS 2010 professionnel, configuration de sortie, optimisé pour la vitesse.

Y a-t-il une explication pour laquelle activer SSE entraîne un temps d'exécution plus long?

2voto

ComicSansMS Points 12749

Il y a un surcoût dans le code SSE pour déplacer les valeurs dans et hors des registres SSE, ce qui peut compenser les avantages de performance de SSE si vous ne faites que très peu de calculs simples, comme c'est le cas avec votre exemple.

Remarquez également que ce surcoût devient significativement plus important si vos données ne sont pas alignées sur 16 octets.

2voto

Walter Points 7554

À mon avis, il n'est souvent pas une bonne idée de compter sur le compilateur pour effectuer ces optimisations. Votre code devrait s'exécuter plus rapidement (à moins que le compilateur ne le fasse déjà pour vous, ce qui ne semble cependant pas être le cas). Je suggère de

1 vous assurer que votre tableau est aligné sur 16 octets

2 utiliser des intrinsèques SSE dans votre fonction d'addition en ligne:

#include 
inline void add(const float * input1, const float * input2, float * output, int size)
{
   // en supposant ici que 
   // - tous les 3 tableaux sont alignés sur 16 octets
   // - la taille est un multiple de 4
   for(int iter = 0; iter < size; iter += 4)
     _mm_store_ps( output+iter, _mm_mul_ps( _mm_load_ps(input1+iter),
                                            _mm_load_ps(input2+iter) ) );
}

si cela ne produit pas de code plus rapide, alors en effet les opérations de chargement et d'enregistrement créent trop de surcharge pour une seule opération de multiplication.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X