IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

x86 32-bits / 64-bits Assembleur Discussion :

Optimisation ratée C++/Asm


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Membre régulier Avatar de Onlava
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2007
    Messages : 92
    Points : 112
    Points
    112
    Par défaut Optimisation ratée C++/Asm
    Bonjour,

    Dans un bout de code c++, j'initialise un entier (non signé) 32bit à la valeur

    le code assembleur donne donc:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    mov DWORD PTR [eax+100], -680876936     ; d76aa478H
    plus tard dans le code, j'additionne la valeur de T1 à un autre entier (non signé) 32bit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    add ebp, DWORD PTR [eax+100]
    sachant que cette valeur T1 va rester constante lors de mes calculs, je me
    suis dit (naviement) que je pourrais remplacer l'instruction ci dessus par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    add ebp, -680876936
    ..afin de me débarasser d'un accès à la mémoire.

    Mais apparament cette technique n'optimise rien du tout, au contraire, le code est plus lent à l'éxécution.
    (sachant que j'ai en réalité 64 variables sembalables à T1, appelées à maintes reprises)

    Ma question : pourquoi est-ce plus lent?
    Merci pour vos avis éclairés =)


    EDIT : testé avec les valeurs ecrites sous forme décimale non-signée. le resultat est le même
    XOR Onlava, Onlava

  2. #2
    Membre confirmé Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Points : 567
    Points
    567
    Par défaut
    Tu as réécrit toute la fonction en assembleur ou tu l'as fait en ASM inline ? Dans le deuxième cas c'est possible que tu embrouilles le compilateur.
    Tu es sûr(e) que le compilateur créait la variable alors qu'elle restait constante ? Si c'est le cas tu as vérifié que les optimisations sont activées (-O3 avec GCC, /O2 avec VC++) ?
    :wq

  3. #3
    Membre régulier Avatar de Onlava
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2007
    Messages : 92
    Points : 112
    Points
    112
    Par défaut
    Citation Envoyé par dapounet Voir le message
    Tu as réécrit toute la fonction en assembleur ou tu l'as fait en ASM inline ? Dans le deuxième cas c'est possible que tu embrouilles le compilateur.
    Tu es sûr(e) que le compilateur créait la variable alors qu'elle restait constante ? Si c'est le cas tu as vérifié que les optimisations sont activées (-O3 avec GCC, /O2 avec VC++) ?
    J'ai d'abord écrit le code en c++, compilé en Ox (full optim) avec output en asm sous vs2008, puis remplacé le code de la function par son équivalent asm en inline.

    Tel quel, le code marche très bien.Mais en y ajoutant les modification citées plus haut, une perte de performance d'environ 6% est observée.

    La varaible a le scope de l'objet dont elle est membre, sa valeur est assignée dans le constructeur, puis accédée dans une méthode membre du même objet.

    Merci pour ton aide.
    XOR Onlava, Onlava

  4. #4
    Membre confirmé Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Points : 567
    Points
    567
    Par défaut
    La différence entre les deux instructions c'est que la deuxième est plus grosse que la première, ça peut être un avantage ou un inconvénient selon les cas. Ce qui est bizarre c'est que normalement une d'addition entière est plus facilement parallélisée et réordonnée qu'un accès mémoire. Si la variable se trouve en cache L1 le temps d'accès n'est pas long (dans les trois cycles).
    Il y a moyen de voir à quoi ressemble le code ?
    :wq

  5. #5
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    225
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 225
    Points : 113
    Points
    113
    Par défaut
    Bon d'abord si t'as activé l'optimisation de GCC, tu n'auras pas besoin de fouiller dans le code Gas produit par celui-ci ... Cherche plutôt à optimiser ton code C plutôt que d'optimiser un code en Asm déjà optimisé .
    Après, faudrait que tu cherches un peu sur la taille de add REG,IMM et le couple d'instructions que t'as utilisé ci-dessus .
    D'ailleurs je remarque que xor ax,ax puis inc ax ou or ax,1 sont moins lourdes que mov ax,1 enfin je n'ai pas appris par coeur la taille et la vitesse d'execution ,pour la vitesse d'execution, ne te contente pas de celles publiées dans la doc. Intel ou AMD, fais tes propres tests avec ton timer, et si ton timer n'est pas très précis, télécharge Bochs ( émulateur PC ) et réduit la vitesse du CPU émulé
    Forum Programmation d'OS - Tutoriel pour créer un petit noyau 32 bits .

    ( le développement de littlefoot86 est abandonné ... )

  6. #6
    Membre confirmé Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Points : 567
    Points
    567
    Par défaut
    Citation Envoyé par bouazza92 Voir le message
    D'ailleurs je remarque que xor ax,ax puis inc ax ou or ax,1 sont moins lourdes que mov ax,1 enfin je n'ai pas appris par coeur la taille et la vitesse d'execution
    Moins lourdes ? À la base il faut déjà éviter de ne pas utiliser des opérandes 32 bits, et ADD est plus rapide que INC... Pour la taille il ne faut pas chercher absolument à utiliser des instructions minuscules, on peut juste les équilibrer quand il y en trop de petites/grosses qui sont groupées. Pour aller plus loin il faut se renseigner sur les (pré)décodeurs du processeur.

    fais tes propres tests avec ton timer, et si ton timer n'est pas très précis, télécharge Bochs ( émulateur PC ) et réduit la vitesse du CPU émulé
    Ça donne vraiment des résultats qui ressemblent à ceux réels ?
    :wq

  7. #7
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    Peut-etre que la valeur constante codee en asm se trouve a cheval entre
    deux adresses 32 bit, et du coup le proc doit faire 2 acces

    a+ Francois

  8. #8
    Membre régulier
    Inscrit en
    Janvier 2006
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 69
    Points : 89
    Points
    89
    Par défaut
    effectivement cela peut avoir une incidence, les compilateurs alignant le code et les données.

    Il faut aussi compter avec les caches du processeur (L1,L2,L3), le processeur garde en cache les données et le code récent. Du coup si la données est encore en cache, l'accès en ram est évité, annulant de surcroit l'optimisation.

    il faut aussi compter sur la taille de l'instruction complète que le CPU doit lire (voir sur combien d'octet les instructions "add ebp, DWORD PTR [eax+100]" et "add ebp, -680876936" prennent).

    faut également vérifier en fonction de ton proc, les cycles théoriques indiqué par le constructeur pour ces 2 opérations

    et je suis sûre qu'il doit avoir encore d'autres facteurs à prendre en compte.

Discussions similaires

  1. Réponses: 28
    Dernier message: 03/06/2009, 09h31
  2. Optimisation ASM x86
    Par youp_db dans le forum x86 32-bits / 64-bits
    Réponses: 4
    Dernier message: 08/06/2008, 14h33
  3. Besoin de routines ASM optimisées pour Delphi
    Par John Fullspeed dans le forum x86 32-bits / 64-bits
    Réponses: 11
    Dernier message: 08/12/2004, 21h00
  4. Frame Rate
    Par starsky dans le forum OpenGL
    Réponses: 6
    Dernier message: 31/08/2002, 00h40
  5. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    Réponses: 2
    Dernier message: 11/06/2002, 10h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo