Optimisation de code assembleur inclus dans du code C

Signaler
Messages postés
11
Date d'inscription
dimanche 2 octobre 2005
Statut
Membre
Dernière intervention
19 avril 2008
-
Messages postés
11
Date d'inscription
dimanche 2 octobre 2005
Statut
Membre
Dernière intervention
19 avril 2008
-
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

Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
29
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++
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
29
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++
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Comment sais-tu que tel parametre est dans tel registre?
et puis normalement avec __fastcall on doit pas faire un ret 4?

Neo_Fr
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
29
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++
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Ok merci, pour ceux qu'ont pas comprit tt est expliquer ici:
http://msdn2.microsoft.com/en-us/library/25687bhx.aspx

Neo_Fr
Messages postés
11
Date d'inscription
dimanche 2 octobre 2005
Statut
Membre
Dernière intervention
19 avril 2008

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
Messages postés
21041
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
29
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++
Messages postés
11
Date d'inscription
dimanche 2 octobre 2005
Statut
Membre
Dernière intervention
19 avril 2008

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.
Messages postés
11
Date d'inscription
dimanche 2 octobre 2005
Statut
Membre
Dernière intervention
19 avril 2008

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.