Question

Je suis en train d'écrire un flux net avant dans VC ++ en utilisant intrinsics AVX. J'invoque ce code par PInvoke en C #. Ma performance lors de l'appel d'une fonction qui calcule une grande boucle, y compris la fonction exp () est ~ 1000ms pour un loopsize de 160M. Dès que je l'appelle any fonction qui utilise AVX intrinsics, puis utilisez ensuite exp (), ma performance chute à environ ~ 8000ms pour la même opération. Notez que la fonction de calcul exp () est standard C, et l'appel qui utilise les valeurs intrinsèques AVX peut être sans aucun rapport en termes de données en cours de traitement. Une sorte de drapeau est déclenché quelque part se lors de l'exécution.

En d'autres termes,

A(); // 1000ms calculates 160M exp() 
B(); // completely unrelated but contains AVX
A(); // 8000ms

ou, curieusement,

C(); // contains 128 bit SSE SIMD expressions
A(); // 1000ms

Je suis perdu à quel mécanisme possible qui se passe ici, ou comment poursuivre une sol'n. Je suis sur un cpu Intel 2500K \ versions Win 7. express de VS.

Merci.

Était-ce utile?

La solution

Si vous utilisez une instruction AVX256, le « AVX ??état supérieur » devient « sale », ce qui se traduit par une grande cabine si vous utilisez ensuite les instructions SSE (y compris à virgule flottante scalaire effectué dans les registres XMM). Ceci est documenté dans le manuel d'optimisation Intel, que vous pouvez télécharger gratuit (et est un incontournable si vous faites ce genre de travail):

instruction AVX modifie toujours les bits supérieurs des registres YMM et instructions SSE ne modifient pas les bits supérieurs. Du point de vue matériel, les bits supérieurs de la collection de registre YMM peuvent être considérés comme dans l'un des trois états:

• Nettoyer: Tous les bits supérieurs de YMM sont nuls. Ceci est l'état lorsque le processeur commence à partir de RESET.

• modifié et enregistré à la région XSAVE Le contenu des bits supérieurs des registres YMM correspondances données enregistrées dans la région XSAVE. Cela se produit lorsque après XSAVE / exécute de XRSTOR.

• modification et non enregistrées. L'exécution d'une instruction AVX (soit 256 bits ou 128 bits) modifie les bits supérieurs du YMM de destination

La pénalité de transition AVX / SSE applique chaque fois que le processeur est états « modifié et non enregistrées ». L'utilisation VZEROUPPER déplacer le processeur états à « Clean » et éviter la peine de transition.

Votre dirties routine B( ) L'état YMM, donc le code SSE dans les stalles de A( ). Insérez une instruction de VZEROUPPER entre B et A pour éviter le problème.

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