Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1458 connectés 

  FORUM HardWare.fr
  Programmation
  ASM

  [ASM/Intrinsics] Code asm généré

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[ASM/Intrinsics] Code asm généré

n°902439
Evadream -​jbd-
Posté le 19-11-2004 à 04:36:55  profilanswer
 

Bonjour tout le monde,
 
Je m'intéresse en ce moment, plus par curiosité que par réel besoin, à l'utilisation des instrinsics pour avoir un accès "aisé" aux capacités SIMD des processeurs. Ayant un AthlonXP, j'ai fais qqs essais afin d'exploiter les instructions SSE. J'ai analysé le code asm généré par le compilateur, et cela soulève plusieurs interrogation. (J'ai compilé en Os parce que si je compile en O3, le compilo court circuite les instructions de la boucle et ne fait le "calcul" qu'une seule fois) :
 
Voici le bout de code et sa "variante" qui vont nous intéresser :
 
Version de base

Code :
  1. /*
  2. * Compilation:
  3. *  
  4. *  asm > gcc -std=c99 -Os -msse -S -c sse.c
  5. *  exe > gcc -std=c99 -Os -msse -c sse.c -o sse     
  6. *
  7. */
  8. #include <stdio.h>
  9. #include <xmmintrin.h>
  10. float a[4] __attribute__((aligned(16))) = { 2.f, 3.f, 4.f, 5.f } ;
  11. float b[4] __attribute__((aligned(16))) = { 5.f, 6.f, 7.f, 8.f } ;
  12. float c[4] __attribute__((aligned(16))) ;
  13. int main(int argc, char* argv[])
  14. {
  15.     for ( int i = 0 ; i < 100000 ; ++i ) {
  16.         for ( int j = 0 ; j < 100000 ; ++j ) {
  17.             _mm_store_ps(c,
  18.             _mm_add_ps( _mm_load_ps(a) ,_mm_load_ps(b)))  ;
  19.         }
  20.     }
  21.     printf("%f %f %f %f\n", c[0], c[1], c[2], c[3]) ;
  22. }


Version de base - les lignes de code assembleur qui m'intéressent

Code :
  1. .L20:
  2.     movaps a, %xmm0
  3.     decl %eax
  4.     movaps b, %xmm1
  5.     addps %xmm1, %xmm0
  6.     movaps %xmm0, c
  7.     jns .L20


Version bis

Code :
  1. /*
  2. * Compilation:
  3. *  
  4. *  asm > gcc -std=c99 -Os -msse -S -c ssebis.c
  5. *  exe > gcc -std=c99 -Os -msse -c ssebis.c -o ssebis       
  6. *
  7. */
  8. #include <stdio.h>
  9. #include <xmmintrin.h>
  10. union sse4 {
  11.     __m128 m ;
  12.     float values[4] ;
  13. } a,b,c ;
  14. int main(int argc, char* argv[])
  15. {
  16.     a.values[0] = 2.f ; a.values[1] = 3.f ; a.values[2] = 4.f ; a.values[3] = 5.f ;
  17.     b.values[0] = 5.f ; b.values[1] = 6.f ; b.values[2] = 7.f ; b.values[3] = 8.f ;
  18.     for ( int i = 0 ; i < 100000 ; ++i ) {
  19.         for ( int j = 0 ; j < 100000 ; ++j ) {
  20.             c.m = _mm_add_ps(a.m, b.m) ;
  21.         }
  22.     }
  23.     printf("%f %f %f %f\n", c[0], c[1], c[2], c[3]) ;
  24. }


Version bis - les lignes de code assembleur qui m'intéressent

Code :
  1. .L17:
  2.     movaps a, %xmm0
  3.     decl %eax
  4.     addps b, %xmm0
  5.     movaps %xmm0, c
  6.     jns .L17


 
Les performances pour les deux versions sont les mêmes en -Os, de même en -O3 en introduisant du travail dans la boucle (en changeant la valeur du vecteur a par exemple). (environ 10 secondes de "calculs" ).
 
N'ayant aucune expérience en assembleur, je me demande comment fonctionne l'instruction addps. D'après ce que j'ai compris (c'est là ou ca coince :p), elle prend en paramètre 2 registres sse afin de mettre le résultat dans un des deux (ici, xmm0, syntaxe AT/T). Or ici, b est un emplacement mémoire arbitraire dans cette version bis. Comme le programme fonctionne, que dois-je en conclure ? Il y a un movaps "caché" [:ddr555] ?  Y'a t'il quelque chose à savoir ou quelque chose qui ne va pas dans mon analyse ?
 
Question subsidiaire : Je n'ai pas l'impression que l'on puisse décider du registre sse à utiliser via les intrinsics, vous confirmez ?
 
Merci d'avance pour vos réponses ! @++
 
Edit : Il est dangereux de poster ce genre de sujet à 4h30 du matin [:banzai]. Je verrais bien ce que ca donne demain !


Message édité par Evadream -jbd- le 19-11-2004 à 05:17:57
mood
Publicité
Posté le 19-11-2004 à 04:36:55  profilanswer
 

n°902461
chrisbk
-
Posté le 19-11-2004 à 08:15:46  profilanswer
 

non, rares sont les instructions prenant exclusivement deux registres. La plupart acceptent une operande en mémoire (ce que l'on apelle le load&execute)

Citation :


 
Question subsidiaire : Je n'ai pas l'impression que l'on puisse décider du registre sse à utiliser via les intrinsics, vous confirmez ?


 
yes sir !


Message édité par chrisbk le 19-11-2004 à 08:16:29
n°902520
Evadream -​jbd-
Posté le 19-11-2004 à 09:26:41  profilanswer
 

Merci pour tes explications.
 
Y'a tellement de point d'interrogation dans mon premier post que je ne sais pas à quoi correspond ton "non" :)
 
Si j'ai bien compris, le load & execute permet d'utiliser des opérandes en mémoire.
Que se passe t'il derrière ? Les opérandes sont chargées dans des registres sse afin que l'opération se fasse bien en même temps sur mes 8 valeurs ? ("non" ? :D).
 
Si oui, est-ce une "bonne" méthode ou bien il est plus efficace de charger çà explicitement dans un registre sse ?
Si ca ne se fait pas comme çà, comment peut-on bénéficier de l'accélération SIMD de l'opération ?
 
C'est dommage de ne pas pouvoir contrôler "finement" l'utilisation des registres via les intrinsics, çà réduit leur champ d'application si on veut vraiment savoir ce qui se passe derrière. Par exemple pour améliorer "l'instruction pairing", ca ne me semble pas évident (lorsque j'ai effectué plusieurs _mm_add_ps_ entres des vecteurs indépendants, seul le registre xmm0 était utilisé). Me trompje où bien y'a t'il une façon d'utiliser les intrinsics "proprement" ?
 
Merci !


Message édité par Evadream -jbd- le 19-11-2004 à 09:33:34
n°902532
chrisbk
-
Posté le 19-11-2004 à 09:40:33  profilanswer
 

Evadream -jbd- a écrit :

Merci pour tes explications.
 
Y'a tellement de point d'interrogation dans mon premier post que je ne sais pas à quoi correspond ton "non" :)
 
Si j'ai bien compris, le load & execute permet d'utiliser des opérandes en mémoire.
 
Que se passe t'il derrière ? Les opérandes sont chargées dans des registres sse afin que l'opération se fasse bien en même temps sur mes 8 valeurs ? ("non" ? :D).


Non :o
 
c'est le CPU qui se demerde derriere
 
padds xmm0,xmm1;
padds xmm0,[eax + 20];
 
les 2 sont valids
 
 

Evadream -jbd- a écrit :


C'est dommage de ne pas pouvoir contrôler "finement" l'utilisation des registres via les intrinsics, çà réduit leur champ d'application si on veut vraiment savoir ce qui se passe derrière. Par exemple pour améliorer "l'instruction pairing", ca ne me semble pas évident (lorsque j'ai effectué plusieurs _mm_add_ps_ entres des vecteurs indépendants, seul le registre xmm0 était utilisé). Me trompje où bien y'a t'il une façon d'utiliser les intrinsics "proprement" ?
 
Merci !


 
Bin tu sais, si tu veux du plus fin fo faire de l'asm inline (les intrinsics te vire la gestion des regs, et c'est a peu pres tout)


---------------
NP: HTTP Error 764 Stupid coder found
n°902575
Evadream -​jbd-
Posté le 19-11-2004 à 10:20:30  profilanswer
 

chrisbk a écrit :


...
Bin tu sais, si tu veux du plus fin fo faire de l'asm inline (les intrinsics te vire la gestion des regs, et c'est a peu pres tout)


 
:D Ok, merci pour toutes tes précisions !


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  ASM

  [ASM/Intrinsics] Code asm généré

 

Sujets relatifs
executer un fichier php dans du code PHP??Code tout bête qui marche pas sous FireFox (??)
[Win] Recensement des techniques d'exécution de code en mode admin.Probleme Insertion code stats dans interface html
Evaluer le texte d'un fichier comme du code C.Passage d'un tableau de string vers du code non managé (DLL)
[ASP] Pas de code sources en clair sur le serveur web ?[JS] Code erroné?
[C] Compiler un code C (from linux) avec un compiler winLire du binaire => code hexadecimal
Plus de sujets relatifs à : [ASM/Intrinsics] Code asm généré


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR