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 :

Rapidité execution instructions


Sujet :

x86 32-bits / 64-bits Assembleur

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 407
    Par défaut Rapidité execution instructions
    Bonjour,

    J'aimerais avoir des certitudes par rapport au faite qu'une instruction peut être plus rapide qu'une autre, parce que personne n'a vraiment l'air d'accord là-dessus.
    Certains disent que calculer le clock rate ne veut rien dire car cela varie selon les versions de proc.

    Mais par rapport aux opcodes, si une instruction comportent un opcode avec moins de byte qu'une autre, sera t-elle forcément plus rapide ?

    Par exemple, pour mettre un registre à "1" le plus rapidement possible.

    mov eax,1 | b8 01 00 00 00

    xor eax,eax | 31 c0
    inc eax | 40

    Peut-on en conclure que la deuxième solution est plus rapide à être executer sous pretexte qu'elle ne comporte que trois bytes ?

    Est-ce que ce sera pareil sous tous les proc compatibles ?

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

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

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Par défaut
    ça pourrait être vrai (et encore...) si le processeur décodait et exécutait les instructions les unes après les autres.

    Mais ça fait un moment que les processeurs savent "préparer" à l'avance
    l'exécution d'une instruction.

    Or, le fait de manipuler un registre sur 2 instructions qui se suivent, l'oblige à terminer l’exécution de la première instruction pour connaître la valeur de ce dernier.

    quand les premiers 486 sont sortis, j'avais modifié quelques programmes
    gourmands en temps d'exécution, en faisant en sorte d'avoir le moins
    souvent possible 2 registres identiques sur 2 lignes.
    en reprenant ton exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    xor ax,ax
    inc ax
    xor bx,bx
    inc bx
    était moins rapide que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    xor ax,ax
    xor bx,bx
    inc ax
    inc bx
    J'arrivais à gagner 10% en vitesse d'exécution de ces programmes !

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 407
    Par défaut
    Ok, merci à toi

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 500
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 500
    Par défaut
    Hello,

    Citation Envoyé par n5Rzn1D9dC Voir le message
    Mais par rapport aux opcodes, si une instruction comportent un opcode avec moins de byte qu'une autre, sera t-elle forcément plus rapide ? Peut-on en conclure que la deuxième solution est plus rapide à être executer sous pretexte qu'elle ne comporte que trois bytes ?
    Pas forcément, car le seul nombre d'octets impliqués ne suffit pas à déterminer la durée d'une instruction. Certaines sont nativement très longues. Ça peut être le cas de « PUSHA » qui empile tous les registres. Le code opération est très concis, mais accomplir l'enregistrement en mémoire de tous les registres demande effectivement du temps.

    Forthman t'a fait une brillante démonstration des effets du pipeline utilisé dans les processeurs modernes. Le fait que le micro-processeur travaille « à la chaîne » en exploitant en permanence chacune de ses unités incite le programmeur à essayer de ne pas « briser » cette chaîne. La minimisation des barrières de synchro est un des leitmotiv de la programmation en parallèle. Mais il y a également d'autres effets dont il faut tenir compte, même sur des micro-processeurs plus modestes. Parmi eux :

    • Les accès bus : très importants, ils peuvent être très pénalisants surtout s'ils sont source de wait states. Dans ton premier exemple, tu lis la donnée depuis la mémoire. Le micro-processeur doit donc faire un accès exclusif au bus, attendre que la RAM affiche la bonne valeur, puis véhiculer la donnée dans le registre concerné. Le fait même d'aiguiller plusieurs octets est en soi consommateur de cycles machines (moins vrai depuis que le micro-processeur comme la mémoire vive sont nativement 32 bits). Mais le vrai problème va venir du fait que l'équipement de ton ordinateur est nettement moins rapide que le micro-processeur lui-même. Il y aura donc des temps d'attente imposés et une monopolisation du bus encore plus pénalisantes si plusieurs périphériques l'exploitent. Ça devient même critique lorsque tu ne lis pas la mémoire vive réservée au code mais une plage de données mappée par le bus PCI. Une transaction a alors lieu pour récupérer une trame de données par rafale.

      A contrario, les instructions de ton second exemple, elles, sont complètement implicites, c'est-à-dire qu'elles se suffisent à elles-mêmes. Toute l'opération a donc lieu au sein du micro-processeur sans avoir à faire une quelconque synchronisation avec l'extérieur. Elles se font donc à pleine vitesse et avec toutes les optimisations possibles.

    • Le RISC (Reduced Instruction Set Chip) : les puces RISC sont des circuits dont le jeu d'instructions est extrêmement limité (par exemple, 16 instructions seulement sur les premières puces RISC) mais qui, en contrepartie, exécutent très vite ces instructions, souvent en un seul cycle !

      Les micro-processeurs complets comme la famille des Intel x86 proposent beaucoup d'instructions qui, initialement, étaient toutes câblées. Mais aujourd'hui, c'est un cœur RISC qui exécutent les instructions les plus fondamentales, les autres étant émulées par un micro-code au cœur de la puce elle-même et s'appuyant sur ces premières. Donc, évidemment, certaines instructions sont devenues nettement plus rapides que d'autres. L'exemple le plus célèbre, ayant pris effet avec la sortie du 486, sont les instructions :
      … devenues plus rapides à elles deux que
      … pourtant uniquement dédiées à cet usage.


    Est-ce que ce sera pareil sous tous les proc compatibles ?
    Malheureusement non ! Ce sera différent d'une version à l'autre et, fort probablement, d'un fondeur à l'autre également.

    Tout ceci devient donc très difficile à gérer, surtout au niveau global (s'il faut savoir si une instruction aura un impact cent lignes plus bas) et encore plus à optimiser. Parallèlement, les compilateurs, eux, sont devenus très efficaces dans ce domaine : ils sont capables de résoudre un programme comme une équation et de privilégier l'usage de certaines ressources au dépit d'autres en fonction de la situation.

    On a longtemps pensé, souvent à raison, qu'un compilateur aussi subtil soit-il ne pouvait rivaliser avec une vraie optimisation « à la main », un peu comme un traducteur automatique ne peut avoir à 100 % la perception d'un traducteur humain. Aujourd'hui, c'est nettement moins vrai : il devient très difficile de battre un compilateur bien affûté sur ce point.

    L'adoption de langages de haut niveau était en soi une nécessité mais ce dernier point est ce qui a précipité l'abandon progressif de la programmation en assembleur par les développeurs. Et c'est dommage.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 407
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    On a longtemps pensé, souvent à raison, qu'un compilateur aussi subtil soit-il ne pouvait rivaliser avec une vraie optimisation « à la main », un peu comme un traducteur automatique ne peut avoir à 100 % la perception d'un traducteur humain. Aujourd'hui, c'est nettement moins vrai : il devient très difficile de battre un compilateur bien affûté sur ce point.

    L'adoption de langages de haut niveau était en soi une nécessité mais ce dernier point est ce qui a précipité l'abandon progressif de la programmation en assembleur par les développeurs. Et c'est dommage.
    Je suis justement tombé sur un exemple qui m'a plus ou moins choqué.
    J'ai codé base64 en asm, et ensuite j'ai voulu comparer mon code en faisant un gcc -S sur un code base64 écrit en C que j'ai trouvé sur le net.

    Le code C en entrée fait environ 100 ligne, et en sortie assembleur, il en fait 650.
    Et avec mingw32msvc-g++ -S, on dépasse les 800 lignes d'asm..

    Sachant que mon code asm perso fait environ 150 lignes..
    Je voulais justement voir comment le compilateur aller réussi à gérer ce genre de code, et si ça tiendrait sur moins de ligne que mon code.

    Et chose étrange, le code asm en version Linux est un mélange d'instruction 32 et 64 bits.
    Par contre le code Win32 de Mingw est uniquement en 32 bits.

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 500
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 500
    Par défaut
    Difficile de te répondre sans voir le code mais, à vue de nez, 100 lignes de C pour coder base64, ça me paraît un poil excessif.

    Par contre, il faudrait déjà que tu actives les options d'optimisation maximum comme -O3 pour que cela change vraiment la donne. Ensuite, beaucoup du code assembleur généré sert à faire l'interface avec le système et/ou le reste de l'application. Il est important d'isoler la partie réellement algorithmique dans ce qui est produit.

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 407
    Par défaut
    Ok, perso je ne sais pas si le code est bon, j'ai lâché le C au bout d'un mois. Je code uniquement par plaisir.
    Le base64 vient de "csmtp", je l'ai eu sur codeproject.

    J'ai l'impression que le compilateur n'arrive pas à le compiler efficacement.
    Autant sur un switch écrit en C, je vois clairement comment c'est optimisé, autant là ça ressemble à rien et c'est énorme..

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 407
    Par défaut
    En tout cas merci pour les explications sur les instructions, c'est exactement ce que je voulais savoir.
    C'est plus ou moins ce que j'avais cru comprendre (en version simplifié), mais avec beaucoup de doute, vu que beaucoup de gens se contredisent.

    a+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. execution instruction sur plusieurs fichiers
    Par mashu dans le forum Langage
    Réponses: 4
    Dernier message: 12/09/2012, 15h30
  2. [AC-2007] Executer instruction dans un champ
    Par ynsoft dans le forum VBA Access
    Réponses: 3
    Dernier message: 11/01/2011, 11h25
  3. [Perf]Probleme de rapidité d'execution
    Par vempiria dans le forum Général Java
    Réponses: 10
    Dernier message: 21/10/2005, 11h38
  4. Rapidité d'execution :RechDom sur Table ou Requete???
    Par samlepiratepaddy dans le forum Access
    Réponses: 4
    Dernier message: 21/09/2005, 16h18
  5. Une instruction s'execute qd on appuie sur entree
    Par nbutin dans le forum C++Builder
    Réponses: 1
    Dernier message: 17/08/2004, 00h48

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