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

 C Discussion :

Échange de code


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Avatar de exe2bin
    Profil pro
    Passionné de programmation
    Inscrit en
    Mars 2009
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Passionné de programmation

    Informations forums :
    Inscription : Mars 2009
    Messages : 537
    Billets dans le blog
    3
    Par défaut Échange de code
    Bonjour à tous ;
    je souhaite remplacer ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Pile[entree_libre++] = i;
    Pile[entree_libre++] = niveau++;
    Pile[entree_libre++] = nbElement--;
    par cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    __asm__
    (
       "pushl %0;pushl %1;pushl %2\n\t"
       "decl %1;incl %2\n\t"
       "addl $3, _entree_libre"
       : "=m" (i), "=m" (nbElement), "=m" (niveau)
       :
       : "memory"
    );
    Puis, plus loin, celui-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    nbElement = Pile[--entree_libre];
    niveau = Pile[--entree_libre];
    i = Pile[--entree_libre];
    par celui-là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    __asm__
    (
       "popl %2;popl %1;popl %0\n\t"
       "subl $3, _entree_libre"
       : "=m" (i), "=m" (nbElement), "=m" (niveau)
       :
       : "memory"
    );
    Mais le programme plante . Quelqu'un voit-il pourquoi ?

  2. #2
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Bonjour,

    La vraie question est : pourquoi vouloir mettre de l'asm ?

    Le compilateur C, avec ses optimisations fait probablement presque aussi bien, et à moins d'appeler ces fractions de code des millions de fois en un temps très bref, tu ne gagneras rien, sinon des ennuis, qui ont donc déjà commencés.

  3. #3
    Membre éclairé
    Avatar de exe2bin
    Profil pro
    Passionné de programmation
    Inscrit en
    Mars 2009
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Passionné de programmation

    Informations forums :
    Inscription : Mars 2009
    Messages : 537
    Billets dans le blog
    3
    Par défaut
    c'est exactement ça ! appeler ce code des milliard de fois ! C'est pour cela que je désire gagner
    des micro-secondes !

  4. #4
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    Par défaut
    Bonjour,

    As-tu vérifié le code généré par le compilateur C ?

    J'ai souvent eu des surprises sur la qualité du code généré par les compilateurs modernes (Visual Studio et GCC), en activant les optimisations.

    J'avais l'habitude de faire de l'assembleur, sérieusement optimisé (en creusant les tables d'instructions, nombre de cycles, etc.), et j'ai peu à peu abandonné, car gagner sur le code généré n'est plus du tout évident, on a plutôt tendance à ralentir le programme (sans que ce soit général, évidemment).

    D'où ma question sur le code généré.

  5. #5
    Membre éclairé
    Avatar de exe2bin
    Profil pro
    Passionné de programmation
    Inscrit en
    Mars 2009
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Passionné de programmation

    Informations forums :
    Inscription : Mars 2009
    Messages : 537
    Billets dans le blog
    3
    Par défaut
    non je n'ai pas examiné le code généré par le compilateur mais je suis certain que tu as raison :
    de nos jours on ne peut faire mieux , sauf pour ce qui concerne les graphiques ;
    néanmoins j'aimerais réaliser ce petit bout de code assembleur.
    Apparement ce sont les pushl et popl qui posent problème ; pour en être sûr j'ai isolé le code
    dans un autre projet en appelant la fonction printf() entre les 2 codes assembleur et ....
    les popfl renvoient des valeurs innatendues !?

    Tu n'as qu'a essayer ce bout de code pour t'en persuader :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int     glob = 10;
     
    int main()
    {
        int     a,b,c;
     
        a = b = c = 50;
        printf("a=%d\tb=%d\tc=%d\tglob=%d\n",a,b,c,glob);
        __asm__
        (
            "pushl %0;pushl %1;pushl %2\n\t"
            "decl %1;incl %2\n\t"
            "addl $3, _glob"
            : "=m" (a), "=m" (b), "=m" (c)
            :
            : "memory"
        );
        printf("a=%d\tb=%d\tc=%d\tglob=%d\n",a,b,c,glob);
        __asm__
        (
            "popl %2;popl %1;popl %0\n\t"
            "subl $3, _glob"
            : "=m" (a), "=m" (b), "=m" (c)
            :
            : "memory"
        );
        printf("a=%d\tb=%d\tc=%d\tglob=%d\n",a,b,c,glob);
     
        return 0;
    }

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 485
    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 485
    Par défaut
    Bonjour,

    Il y a plusieurs choses qui me déroutent dans ton code mais la première est qu'en principe, l'assembleur ne doit contenir qu'une seule instruction par ligne, et ce parce que les différentes « colonnes » (en fait les champs séparés par des espaces ou une tabulation) ont une sémantique : le premier est l'étiquette (même si parfois, en assembleur Intel, on la fait suivre de « : »), le second est l'instruction proprement dite, le troisième est l'opérande, qui obéit normalement à une grammaire spécifique incluant notamment les modes d'adressage, et les quatrième et suivants étant les commentaires.

    L'assembleur Intel comme certains autres tentent de limiter ces ambiguïtés en introduisant des délimiteurs spécifiques comme « ; » pour les commentaires. Autrement dit, tout ce qui suit la première instruction de chaque ligne est considéré comme en dehors du code. C'est flagrant avec gcc -S :

    Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    # 12 "code.c" 1
            pushl -12(%ebp);pushl -16(%ebp);pushl -20(%ebp)
            decl -16(%ebp);incl -20(%ebp)
            addl $3, glob
    # 0 "" 2

  7. #7
    Membre Expert
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Par défaut
    Citation Envoyé par exe2bin Voir le message
    Tu n'as qu'a essayer ce bout de code pour t'en persuader :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int     glob = 10;
     
    int main()
    {
        int     a,b,c;
     
        a = b = c = 50;
        printf("a=%d\tb=%d\tc=%d\tglob=%d\n",a,b,c,glob);
        __asm__
        (
            "pushl %0;pushl %1;pushl %2\n\t"
            "decl %1;incl %2\n\t"
            "addl $3, _glob"
            : "=m" (a), "=m" (b), "=m" (c)
            :
            : "memory"
        );
        printf("a=%d\tb=%d\tc=%d\tglob=%d\n",a,b,c,glob);
        __asm__
        (
            "popl %2;popl %1;popl %0\n\t"
            "subl $3, _glob"
            : "=m" (a), "=m" (b), "=m" (c)
            :
            : "memory"
        );
        printf("a=%d\tb=%d\tc=%d\tglob=%d\n",a,b,c,glob);
     
        return 0;
    }
    Bonjour,
    tu utilises la pile système, mais tu ne modifies pas le pointeur de pile. Ton printf n'est pas au courant de ce que tu as empilé … et «y fout le bordel».
    Enfin je suppose, l'assembleur n'est pas ma tasse de thé. C'est rigolo car je pense que tu passes par une gestion propre de la pile pour t'éviter des appels récursifs et donc l'utilisation de la pile système, puis tu y reviens pour gagner quelques cycles … en terme d'optimisation par compilo cela s'appelle le stack unrolling, je crois (à vérifier).

    J'imagine également que tu travailles sur ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    void    iter(int n,int nbElement,struct noeud *ptr)
    {
        struct  noeud   *p = ptr;
        int     i,niveau = n;
        long    count = 0;
     
    A:  i = nbElement;
        while(i>0)
        {
            if(niveau != nombre_d_items)
            {
                Pile[entree_libre++] = i;
                Pile[entree_libre++] = niveau++;
                Pile[entree_libre++] = nbElement--;
                p = p->suivant;
                goto A;
            B:  p = p->precedant;
                nbElement = Pile[--entree_libre];
                niveau = Pile[--entree_libre];
                i = Pile[--entree_libre];
                /*if(niveau == nombre_d_items-1) {printListe();printf("\t");}*/
                if(++count == 53971002) {printListe();}
                insererApres(supprimerAvantZ(),p);
            }
            i--;
        }
        if(!pileVide()) goto B;
    }
    Plus tu feras du code spaghetti avec des goto vers et hors une boucle, plus tu vas compliquer le boulot d'optimisation du compilo. Il est souvent beaucoup plus profitable d'écrire un code simple que le compilo va optimiser qu'un code supposément optimisé que le compilo ne va que traduire.

    Une dernière remarque, ton code est limité à win32 avec tes morceaux asm, il ne compileras pas en 64bit ou sous linux par exemple. Il est peut-être préférable de faire un code que tu pourras paralléliser ou implémenter (enfin le compilo) avec des instructions avancées SIMD/MMX et autre SSE …

    Edit: à propos ton premier code fonctionne sous linux64 avec quelques aménagement, car l'ABI linux64 passe les paramètres int dans des registres sans les empiler …

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

Discussions similaires

  1. De la rapidité du code
    Par jfloviou dans le forum Contribuez
    Réponses: 233
    Dernier message: 29/05/2009, 02h17
  2. code pour interbase 6.0 et 6.5 de generateur
    Par tripper.dim dans le forum InterBase
    Réponses: 4
    Dernier message: 01/07/2002, 11h29
  3. [MFC](encapsulation ADO) ou placer le code
    Par philippe V dans le forum MFC
    Réponses: 2
    Dernier message: 13/06/2002, 14h58
  4. Explorateur de code C
    Par Zero dans le forum C
    Réponses: 14
    Dernier message: 06/06/2002, 09h41
  5. OmniORB : code sous Windows et Linux
    Par debug dans le forum CORBA
    Réponses: 2
    Dernier message: 30/04/2002, 17h45

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