Aligner des données pour le SSE

Signaler
Messages postés
83
Date d'inscription
samedi 21 mai 2005
Statut
Membre
Dernière intervention
22 mars 2011
-
Messages postés
83
Date d'inscription
samedi 21 mai 2005
Statut
Membre
Dernière intervention
22 mars 2011
-
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
   
    mov edi,Offset HgBuffer2SSE
    movaps HgXmm0,Xmm0
    movaps HgXmm1,Xmm1
    mov eax,HgXmm0
    mov ebx,HgXmm0+4
    mov ecx,HgXmm0+8
    mov [edi],eax
    mov [edi+16],ebx
    mov [edi+32],ecx
    mov [edi+4],eax
    mov [edi+16+4],ebx
    mov [edi+32+4],ecx
    mov [edi+8],eax
    mov [edi+16+8],ebx
    mov [edi+32+8],ecx
    mov [edi+12],eax
    mov [edi+16+12],ebx
    mov [edi+32+12],ecx
   
    mov eax,HgXmm1
    mov ebx,HgXmm1+4
    mov ecx,HgXmm1+8
    mov [edi+48],eax
    mov [edi+64],ebx
    mov [edi+80],ecx
    mov [edi+48+4],eax
    mov [edi+64+4],ebx
    mov [edi+80+4],ecx
    mov [edi+48+8],eax
    mov [edi+64+8],ebx
    mov [edi+80+8],ecx
    mov [edi+48+12],eax
    mov [edi+64+12],ebx
    mov [edi+80+12],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.

13 réponses

Messages postés
83
Date d'inscription
samedi 21 mai 2005
Statut
Membre
Dernière intervention
22 mars 2011

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 ...
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
29
Regarde si ton assembleur a une directive
ALIGN xxx

ciao...
BruNews, MVP VC++
Messages postés
31
Date d'inscription
vendredi 31 décembre 2004
Statut
Membre
Dernière intervention
31 juillet 2008

Pourquoi ALIGN 4 et non ALIGN 16 
-> 16 octets = 128 bits

Patrick
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
29
ah oui, je n'avais pas lu son listing.
ALIGN y est, suffit donc de 16 au lieu de 4.

ciao...
BruNews, MVP VC++
Messages postés
83
Date d'inscription
samedi 21 mai 2005
Statut
Membre
Dernière intervention
22 mars 2011

DataSSE SEGMENT PAGE PUBLIC 'DATA'
ALIGN 16

Non, j'ai toujours 6400ms ou 3900ms (1/4 de l'un et 3/4 de l'autre), sur un même '.exe' ...
Désolé ...
Messages postés
31
Date d'inscription
vendredi 31 décembre 2004
Statut
Membre
Dernière intervention
31 juillet 2008

S'il s'agit d'un problème d'alignement tu peux vérifier d'après les adresses indiquées avec un débugger.
(En particulier pour HgXmm0)

a+

Patrick
Messages postés
83
Date d'inscription
samedi 21 mai 2005
Statut
Membre
Dernière intervention
22 mars 2011

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 ...
Messages postés
31
Date d'inscription
vendredi 31 décembre 2004
Statut
Membre
Dernière intervention
31 juillet 2008

http://www.ollydbg.de/odbg110.zip

ou
http://www.smidgeonsoft.com/download/PEBrowseDbg.zip

a+

Patrick

P.S. : Si tu peux envoyer 2 de tes programmes incriminés
ici : [mailto:patrick.ruiz@tiscali.fr patrick.ruiz@tiscali.fr] 
Merci 
Messages postés
83
Date d'inscription
samedi 21 mai 2005
Statut
Membre
Dernière intervention
22 mars 2011

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Word.Document" />
<meta name="Generator" content="Microsoft Word 9" />
<meta name="Originator" content="Microsoft Word 9" />
<link rel="File-List" href="file:///C:/DOCUME%7E1/COMPAQ%7E1/LOCALS%7E1/Temp/msoclip1/01/clip_filelist.xml" />
<!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:HyphenationZone>21</w:HyphenationZone>
<w:DoNotOptimizeForBrowser/>
</w:WordDocument>
</xml><![endif]-->
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"Arial Unicode MS";
panose-1:2 11 6 4 2 2 2 2 2 4;
mso-font-charset:128;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-1 -369098753 63 0 4129279 0;}
@font-face
{font-family:"\@Arial Unicode MS";
panose-1:2 11 6 4 2 2 2 2 2 4;
mso-font-charset:128;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-1 -369098753 63 0 4129279 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";}
h1
{mso-style-next:Normal;
margin:0cm;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
page-break-after:avoid;
mso-outline-level:1;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-font-kerning:0pt;
font-weight:bold;}
a:link, span.MsoHyperlink
{color:blue;
text-decoration:underline;
text-underline:single;}
a:visited, span.MsoHyperlinkFollowed
{color:purple;
text-decoration:underline;
text-underline:single;}
p
{margin-right:0cm;
mso-margin-top-alt:auto;
mso-margin-bottom-alt:auto;
margin-left:0cm;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Arial Unicode MS";}
pre
{margin:0cm;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
tab-stops:45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;
font-size:10.0pt;
font-family:"Arial Unicode MS";}
@page Section1
{size:612.0pt 792.0pt;
margin:70.85pt 70.85pt 70.85pt 70.85pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style>
This is an automatically generated Delivery Status Notification.
Delivery to the following recipients failed.
[mailto:patrick.ruiz@tiscali.fr patrick.ruiz@tiscali.fr]



<!--[if !supportEmptyParas]-->


<!--[endif]-->





Désolé, ça ne marche pas .... (même les mails plantent avec moi, je suis trop balèze ).
Messages postés
31
Date d'inscription
vendredi 31 décembre 2004
Statut
Membre
Dernière intervention
31 juillet 2008

Essaie alors à cette adresse : patrick.ruiz@aliceadsl.fr

Merci.
Messages postés
83
Date d'inscription
samedi 21 mai 2005
Statut
Membre
Dernière intervention
22 mars 2011

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Word.Document" />
<meta name="Generator" content="Microsoft Word 9" />
<meta name="Originator" content="Microsoft Word 9" />
<link rel="File-List" href="file:///C:/DOCUME%7E1/COMPAQ%7E1/LOCALS%7E1/Temp/msoclip1/01/clip_filelist.xml" />
<!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:HyphenationZone>21</w:HyphenationZone>
<w:DoNotOptimizeForBrowser/>
</w:WordDocument>
</xml><![endif]-->
<style>
<!--
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";}
@page Section1
{size:612.0pt 792.0pt;
margin:70.85pt 70.85pt 70.85pt 70.85pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style>

Cette fois ça marche





Pour les autres, voici un résumé :




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
Messages postés
83
Date d'inscription
samedi 21 mai 2005
Statut
Membre
Dernière intervention
22 mars 2011

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.
Messages postés
83
Date d'inscription
samedi 21 mai 2005
Statut
Membre
Dernière intervention
22 mars 2011

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
   
    movaps Xmm2,Xmm6
    shufps Xmm2,Xmm2,10101010b    ;=> ZZZZ
       
    movss Xmm3,Xmm7
    shufps Xmm3,Xmm3,00000000b    ;copie 4 fois la valeur n°0 depuis Xmm3 vers Xmm3 => XXXX
   
    movaps Xmm4,Xmm7
    shufps Xmm4,Xmm4,01010101b    ;=> YYYY
   
    movaps Xmm5,Xmm7
    shufps Xmm5,Xmm5,10101010b    ;=> ZZZZ
   
    ret
------------------------------------