Optimisation de code assembleur inclus dans du code C

fred_82 Messages postés 11 Date d'inscription dimanche 2 octobre 2005 Statut Membre Dernière intervention 19 avril 2008 - 26 mars 2008 à 15:12
fred_82 Messages postés 11 Date d'inscription dimanche 2 octobre 2005 Statut Membre Dernière intervention 19 avril 2008 - 27 mars 2008 à 15:02
Bonjour,

Alors j'explique le problème, j'aimerais faire une petite fonction en assembleur que j'inclus dans du code C, le probleme est que cette fonction n'est absolument pas optimisé par le compilateur.
Exemple :
je creer une fonction asm qui fait une addition :

int add(int a,int b){
   int c;
   _asm{
       mov eax,a;
       mov ebx,b;
       add eax,ebx;
       mov c,eax;
   }
   return(c);
}

puis dans ma fonction principale j'utilise les deux manière de faire l'addition ( + et ma fonction add) :

void main(){
   int a;
   int b;
   int c;
   int d;


   scanf("%d",&a);
   scanf("%d",&b);
   scanf("%d",&c);
   scanf("%d",&d);


   a=a+b+c+d;
   a=add(add(a,b),add(c,d));
}

Je compile tout ca en release et j'obtient le code asm suivant :
pour le + :
mov         ecx,dword ptr [esp+2Ch]
mov         edx,dword ptr [esp+30h]
add         edx,ecx
add         edx,dword ptr [esp+34h]
add         esp,20h
add         dword ptr [esp+8],edx

soit 6 instructions, on voit bien que le code a été optimisé ici

Par contre avec ma fonction add j'obtiens:
mov         eax,dword ptr [esp+0Ch]
mov         ebx,dword ptr [esp+10h]
add         eax,ebx
mov         dword ptr [esp+18h],eax
mov         eax,dword ptr [esp+18h]
mov         dword ptr [esp+20h],eax
mov         eax,dword ptr [esp+8]
mov         ebx,dword ptr [esp+14h]
add         eax,ebx
mov         dword ptr [esp+1Ch],eax
mov         ecx,dword ptr [esp+1Ch]
mov         dword ptr [esp+24h],ecx
mov         eax,dword ptr [esp+24h]
mov         ebx,dword ptr [esp+20h]
add         eax,ebx
mov         dword ptr [esp+28h],eax

Soit 16 instructions, le compilateur se contente de réécrire le code que j'ai mis dans ma fonction.

Donc ma question est : serait il possible d'écrire une fonction en assembleur et que celle ci soit optimisé par le compilateur? Si oui , comment fait on?

Merci

9 réponses

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
26 mars 2008 à 15:30
NON direct et définitif à ta question.

De l'ASM "dans" du C ne fera que empêcher toute optimisation du compilo.
Bien entendu que le compilo reporte ce qui est mis en ASM, il ne peut rien faire de plus.

On met une fonction FULL ASM ou FULL C mais jamais de mixage.

ciao...
BruNews, MVP VC++
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
26 mars 2008 à 15:34
ah oui un exemple de ADD:

__declspec(naked) int __fastcall bnADD(int a, int b)
{
  __asm {
    lea eax, [ecx+edx]
    ret 0
  }
}

Voila une vraie ADD en 2 lignes.

ciao...
BruNews, MVP VC++
0
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
26 mars 2008 à 16:08
Comment sais-tu que tel parametre est dans tel registre?
et puis normalement avec __fastcall on doit pas faire un ret 4?

Neo_Fr
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
26 mars 2008 à 16:57
Elles ne sont pas cohérentes tes 2 questions.
Puisque les params sont en registre, il n'y a rien à dépiler donc 'ret 0'.

C'est le proto d'appel (ici __fastcall) qui dit à l'appelant où mettre les params et qui dépilera si besoin.

ciao...
BruNews, MVP VC++
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
26 mars 2008 à 17:55
Ok merci, pour ceux qu'ont pas comprit tt est expliquer ici:
http://msdn2.microsoft.com/en-us/library/25687bhx.aspx

Neo_Fr
0
fred_82 Messages postés 11 Date d'inscription dimanche 2 octobre 2005 Statut Membre Dernière intervention 19 avril 2008
26 mars 2008 à 18:56
Merci a tous d'avoir repondu aussi rapidement, en faite je m'explique, j'ai un programme dans lequel j'utilise des instruction SIMD (SSE,SSE2 et autre) le probleme est que certaine intrinsic ne sont pas reconnnu par le compilo de visual , mais aller savoir pourquoi, elles sont reconnu en assembleur. De plus, j'aimerais pouvoir manipuler mes vecteur de la meme façon que je le ferais sous GCC, c'est pourquoi j'aimerais creer ma propre bibliotheque xmmintrin, emmintrin.h et pmmintrin.h.
J'ai donc pensé à les codé moi meme en assembleur.
Voila

Je vais tout de meme essayer la solution de brunews pour voir ce que ca donne.

Merci
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
26 mars 2008 à 19:33
VC++ 2008 reconnait les instructions jusqu'au SSE3.

Je ne sais pas ce que tu fais sous GCC mais attention qu'on ne joue pas avec l'ASM, il faut une extrême rigueur et une longue pratique avant de faire mieux qu'un compilo moderne. Au vu de ce qui est plus haut, il va falloir t'entrainer encore longuement et surtout bien comparer les perfs d'une fonction C et ASM.

Pour ce qui est de SSE, il y a une option du compilo pour lui faire employer SSE au lieu de la FPU. Ceci dit SSE se code en ASM si on veut l'exploiter pleinement, un compilo C est incapable de faire des instructions packées.
Jette un oeil ici:
RECHERCHE MINI ET MAXI EN C ET SSE (WIN32)
http://www.cppfrance.com/code.aspx?ID=44277
COMPARAISON C ET SSE2/3 (WIN32)
http://www.cppfrance.com/code.aspx?ID=41536http://www.cppfrance.com/code.aspx?ID=41536

ciao...
BruNews, MVP VC++
0
fred_82 Messages postés 11 Date d'inscription dimanche 2 octobre 2005 Statut Membre Dernière intervention 19 avril 2008
27 mars 2008 à 14:56
Le compilo de visual ne permet de cast de __m128 en __m128i (pour visual 2005), certes visual 2008 le permet via une intrinsic mais je possede une version complete de visual 2005 (grace a msdnaa) et cela m'ennui de passer à visual express 2008 surtout que certain utilitaire ne sont pas present.
0
fred_82 Messages postés 11 Date d'inscription dimanche 2 octobre 2005 Statut Membre Dernière intervention 19 avril 2008
27 mars 2008 à 15:02
Les compilo optimise mal en SSE lorsque l'on code en scalaire, par contre lorsque l'on dirige le compilo en codant soit meme en scalaire, le resultat est tout a fait satisfaisant.
0
Rejoignez-nous