2017-08-05 5 views
-1

En utilisant intrinsics AVX et algorithme de sommation Kahan, j'ai essayé ceci (juste une partie de "vipère"):g ++ 6.3, sommation Kahan sur intrinsics AVX obtenir sérialisé avec mot-clé volatile

void add(const __m256 valuesToAdd) 
{ 
    volatile __m256 y = _mm256_sub_ps(valuesToAdd, accumulatedError); 
    volatile __m256 t = _mm256_add_ps(accumulator,y); 
    accumulatedError = _mm256_sub_ps(_mm256_sub_ps(t,accumulator),y); 
    accumulator = t; 
} 

il n'y a pas d'erreur mais quand je vérifie le désassemblage (enregistrement perf, rapport dans ubuntu), il montre tous les éléments de l'accumulateur, y et les variables accumulatedError sont calculées une par une, de manière scalaire. Comment peut-on définir une variable intrinsèque qui peut garder son «ordre des opérations» et être toujours utilisée (comme vectorisée) dans une instruction intrinsèque sans être optimisée? Pour s'assurer que c'est vraiment scalaire, j'ai enlevé volatile, il est devenu plus rapide.

Existe-t-il un moyen de dire à gcc que j'ai besoin d'une variable/d'un code vectorisé mais que rien d'autre ne doit être touché?

+3

Qu'essayez-vous d'accomplir avec 'volatile'? Pour empêcher une variable locale d'être optimisée? Pourquoi auriez-vous besoin de ça? 'volatile 'ne présente aucun avantage pour une variable locale basée sur une pile. Avec ce mot-clé là, le compilateur traite apparemment l'accès à chaque flottant comme un accès distinct distinct en supposant qu'ils pourraient changer entre les accès lorsqu'ils sont faits linéairement (non sérialisés), donc l'AVX intrinsèque est codé pour émuler ce comportement. – 1201ProgramAlarm

+0

Alors, ma seule option est d'utiliser inline-asm pour faire des opérations ordonnées non-changeantes? –

+0

Je ne sais pas. Je ne comprends pas ce que vous essayez d'accomplir. – 1201ProgramAlarm

Répondre

3

Si vous voulez explicitement prévenir l'optimisation des mathématiques associative, ne pas utiliser volatile mais les désactiver en utilisant un attribut de fonction:

__attribute__ ((optimize("no-fast-math"))) 
inline void add(const __m256 &valuesToAdd) 
{ 
    __m256 y = _mm256_sub_ps(valuesToAdd, accumulatedError); 
    __m256 t = _mm256_add_ps(accumulator, y); 
    accumulatedError = _mm256_sub_ps(_mm256_sub_ps(t, accumulator), y); 
    accumulator = t; 
} 

Live Demo. Jouez avec des drapeaux et des attributs de compilation. Cet attribut ne semble pas fonctionner avec clang (je suppose qu'il y a quelque chose d'équivalent, mais votre question était spécifique à g ++).

+0

Je compare avec la solution d'assemblage en ligne. Si la performance est comparable, cela ne vaut que pour Boeing gcc. Je vous remercie –