epineurien
Messages postés83Date d'inscriptionsamedi 21 mai 2005StatutMembreDernière intervention22 mars 2011
-
26 juil. 2008 à 11:50
epineurien
Messages postés83Date d'inscriptionsamedi 21 mai 2005StatutMembreDernière intervention22 mars 2011
-
6 août 2008 à 16:58
Bonjour à tous !
J'ai un petit problème avec du code dont je mesure la vitesse: suivant la compilation, la vitesse varie du simple au double .
J'explique : je mesure la vitesse du code ASM si dessous, en général j'obtiens 6800ms.
Si je recompile (sans changer aucune option, sans touché au code) une fois sur trois le nouvel exécutable a une vitesse de 3800ms !
Vu que les deux instructions SSE prennent la majeure partie du temps (et que les movaps semble plus lents que les movups !), je suspecte un truc au niveau de l'alignement des données.
J'avais bêtement supposé que le début d'un '.data' était toujours aligné sur 128bits, et qu'il suffisait de caser toutes les données SSE au début du segment pour qu'elles restent alignées.
Là, après de multiple tentative de bidouillage avec les déclarations manuelles, je rend les armes : movups reste le plus rapide, signe que je n'aligne pas correctement les données.
Donc si quelqu'un pouvait me faire la grâce d'un lien vers un cours expliquant clairement comment alignés des données sur 16 octets, je lui dit merci.
Parce que je teste des trucs depuis ce matin, en suivant ce que je trouve sur le net, mais c'est toujours pas aligné ...
Ma dernière tentative en date :
<hr size="2" width="100%" />DataSSE SEGMENT DWORD PUBLIC 'DATA'
ALIGN 4
.........données SSE (toujours des multiples de 128bits)
HgXmm0 REAL4 4 Dup (0.0e0)
HgXmm1 REAL4 4 Dup (0.0e0)
HgBufferSSE REAL4 32 DUP (0.0e0)
HgBuffer2SSE REAL4 32 DUP (0.0e0)
.........données SSE (toujours des multiples de 128bits)
DataSSE ENDS
<hr size="2" width="100%" />Ne change strictement rien, toujours 1 chance sur 3 d'avoir un truc rapide au lieu d'un truc lent.
Le code ASM :
<hr size="2" width="100%" />HgCalcul PROC
push edi
push eax
push ebx
push ecx
pop ecx
pop ebx
pop eax
pop edi
ret
HgCalcul ENDP
<hr size="2" width="100%" />
La compilation se fait sous Visual C++ 2008, au cas où ça pourrait vous aider.
Merci encore ...
<hr size="2" width="100%" />Jetez un coup d'œil à mon projet de moteur 3D par lancer de rayons :
http://hydrargyrum.ifrance.com.
epineurien
Messages postés83Date d'inscriptionsamedi 21 mai 2005StatutMembreDernière intervention22 mars 2011 26 juil. 2008 à 12:50
Nouvelle série de test, avec :
.data
DataSSE SEGMENT PAGE PUBLIC 'DATA'
....
DataSSE ENDS
J'obtiens dans les 3 quarts des cas 3800ms et dans un quart 7000ms.
Et apparemment, la compilation n'a rien à voir ; un même fichier exécutable peut donner les deux valeurs, suivant son humeur ...
C'est de plus en plus bizarre ...
epineurien
Messages postés83Date d'inscriptionsamedi 21 mai 2005StatutMembreDernière intervention22 mars 2011 28 juil. 2008 à 13:22
Euh ... je ne sais pas me servir d'un débuggeur (fait tout à la main avec des test de sorties, pas bien je sais).
Il y a quoi de bien comme logiciel de débuggage ? Parce que celui de VSC++ est vraiment bordélique ...
Ce que je trouve bizarre c'est que ca varie du simple au double sur un même exécutable ; normalement, soit les données sont alignées, soient elles ne le sont pas, non ? Il ne devrait y avoir aucune raison que ce soit des fois alignés et des fois non.
En fait je ne suis même pas sûr que ce soit une histoire d'alignement, c'est juste que je ne voit ce que ça peut être d'autre :
-movaps de même vitesse que movups (alors qu'il est sensé être plus rapide)
-les deux instructions SSE prenne la majeure partie du temps (si on les virent on passe à un temps de 610ms, invariable).
Mais si c'est pas l'alignement (d'aprés le net ALIGN 16 and co devraient avoir résolut le problême) je vois pas ce que cela peut être ...
J'ai aussi testé une histoire avec le cache, au cas où se serait le tampon qui pose problême et pas les movaps :
mov edi,Offset HgBuffer2SSE
prefetchNTA BYTE PTR [edi]
prefetchNTA BYTE PTR [edi+64]
movaps HgXmm0,Xmm0
movaps HgXmm1,Xmm1
J'ai gagné quelques ms mais j'ai toujours ce fonctionnement à vitesse variable.
Je me met en quête d'un débuggeur et d'un manuel d'utilisation ...
Les données se retrouvent à l’offset 0408000h, même avec un
simple ‘.data’ (avec une déclaration manuelle , SEGMENT , ALIGN et compagnie, j’arrive
pas à remettre la main sur les données SSE.)
Bref, même avec un ‘.data’ tout simple, les données sont
alignées sur 128bits.
Donc cette vitesse variable ne semble pas venir de là, et
franchement je ne vois pas ce que ça peut être...
Quelqu’un connaît un mécanisme dont la vitesse peut varier du simple au
double entre deux lancements d’un même exécutable
epineurien
Messages postés83Date d'inscriptionsamedi 21 mai 2005StatutMembreDernière intervention22 mars 2011 5 août 2008 à 16:16
Bon, nouvelle série de test : si l'alignement est volontairement brisé, il y a plantage du programme (l'intérêt de lire les doc techniques après coup ).
Donc ce topic perd sa raison d'être, mon problème ne vient pas de l'alignement SSE.
Ça doit quand même venir des movaps, puisque ils représentent 90% du temps du calcul, et sont donc les seuls à avoir assez de poids pour provoquer ses changements.
epineurien
Messages postés83Date d'inscriptionsamedi 21 mai 2005StatutMembreDernière intervention22 mars 2011 6 août 2008 à 16:58
Fin de l'histoire avec une nouvelle approche (via shufps), infiniment plus rapide et sans vitesse variable.
Pour ceux que ça intéresse, l'usage de movntps (passage sans le cache) est dix fois plus rapide dans mes tests que l'usage de movaps (dans le cas Registre SSE => mémoire).
------------------------------------
;Xmm6 contient les coordonnées X,Y,Z du point 1
;Xmm7 contient les coordonnées X,Y,Z du point 2
movss Xmm0,Xmm6 ;on ne transfère que celui du bas
shufps Xmm0,Xmm0,00000000b ;copie 4 fois la valeur n°0 depuis Xmm0 vers Xmm0 => XXXX
movaps Xmm1,Xmm6 ;on ne transferte que les deux du bas
shufps Xmm1,Xmm1,01010101b ;=> YYYY