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

Langage C++ Discussion :

assembleur et template


Sujet :

Langage C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 9
    Points : 6
    Points
    6
    Par défaut assembleur et template
    Bonjour,
    J'écris une petite librairie d'arithmétique statique, contrairement à GMP qui est dynamique. Pour obtenir de bonne perf je dois écrire en assembleur.
    Si je considere une addition de grand entier (>64 bits), j 'utilise un tableau de long int. Si je considère ma fonction addition je devrai tout d'abord loader mes datas (en assembleur x86-64, gas)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      void vli256_add(boost::uint64_t * /*%%rdi*/, boost::uint64_t const * /*%%rsi*/) {
                                    asm (
                                            "movq  (%%rdi), %%r8 " // load la 1 ere data
                                            "movq  0x08(%%rdi), %%r9"  // load la 2eme  data  successive
    Cette structure marche très bien mais elle suppose que mes datas soit stockées sous le format AoS, pour divers raisons je souhaite utiliser le modèle SoA.

    Je rappelle AoS : si on considère un grand entier A comme la suite de 2 long int (a0 et a1), en mémoire on a : a0a1 si je prend B C et D , j obtiendrai en mémoire a0a1 b0b1 c0c1 d0d1 le tout continue, en AoS, j obtiens
    a0b0c0d0 a1b1c1d1. L'idée est d'ajouter un paramètre template pour permettre de passer d'une représentation à une autre. en pseudo code j'obtiendrai:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template< int n>
      void vli256_add(boost::uint64_t * /*%%rdi*/, boost::uint64_t const * /*%%rsi*/) {
                                    asm (
                                            "movq  (%%rdi), %%r8" //idem                                                                            
                                            "movq  0x08*n(%%rdi), %%r9 "// n donne l offset n=1 SoA, n=4 AoS  "
    le pb et que n est dans une string donc il ne sera pas considéré un nombre.
    Bref je ne sais pas trop comment mixer cette string d'assembleur et ce paramètre template ... (je suis un débutant en assembleur)

  2. #2
    Membre éclairé
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Points : 879
    Points
    879
    Par défaut
    Pourquoi ne pas faire deux fonctions ?

    Sinon, il me semble qu'il est impossible de faire ça avec des templates. Peut-être générer les deux fonctions avec une macro, si la fonction est trop longue ?

    Sinon, au passage, je dois réagir à "Pour obtenir de bonne perf je dois écrire en assembleur."
    C'est totalement faux !
    Le c++ peut parfaitement produire du code parfaitement optimisé !
    Au passage, le compilateur produira très probablement du code au moins aussi optimisé que toi, après avoir vu le code c++. Surtout que, comme tu le dis toi-même, "[tu es] un débutant en assembleur".

    Donc mieux vaudrait pour toi écrire en c++. Quitte à optimiser certains bouts particulièrement critiques en assembleur, si le profilage et l'étude du code généré l'indique nécessaire.

  3. #3
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    Ecris le truc en C++ deja, mates le code généré et avise aprés.
    Ecrire de l'assembleur inline, c'ets aller au tas.

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Bonsoir, bien sur, j'ai déjà écrit une une première release en C++ où je fais tout à la main (la gestion du carry bit), (je fais des opérations sur les polynômes avec des grands entier, ça marche, je fais de la programmation hybride OpeMP/CUDA), mais le chef n'est jamais content

    Néanmoins la gestion du carry bit peut être fait par l'instruction assembleur adcq ... Je viens de terminer mon addition 196 en assembleur, ça ressemble à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void add_196(unsigned long int* /* %%rdi */, unsigned  long int const* /* %%rsi */){
          asm(
              "movq  (%%rdi), %%r8       \n"
              "movq  0x08(%%rdi), %%r9   \n"
              "movq  0x10(%%rdi), %%rcx  \n"
              "addq  (%%rsi), %%r8       \n"
              "adcq  0x08(%%rsi), %%r9   \n"
              "adcq  0x10(%%rsi), %%rcx  \n"
              "movq  %%r8, (%%rdi)       \n"
              "movq  %%r9, 0x08(%%rdi)   \n"          
              "movq  %%rcx, 0x10(%%rdi)  \n"          
              : : : "rsi","rdi","rcx","r8","r9","memory"
             );
    }
    Une version pure C++ ressemble à ça ( le tout dans une boucle)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            template <typename BaseInt, std::size_t Order>
            inline void kernels_addition_block(BaseInt* x, BaseInt const* y){
                *x         += *y; 
                *(x+Order) += *x >> data_bits<BaseInt>::value; //carry bit <- C'est ce Order que je veux passer en parametre template 
                *x         &= data_mask<BaseInt>::value; // Remove the carry bit
            }
    Pour revenir à ma question, peut on modifier la string de l'assembleur avec un paramètre template, je pense que non ... Bien que le compilo c'est le faire ...

    Pour mon niveau débutant au assembleur c'est +- vrai, j'ai fait beaucoup de programmation SSE, mais on peut utiliser des instructions du C++ pour utiliser ces registres. Cette maudite instruction adc n'est pas dispo en C++

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Comme les autres j'ai de gros doute sur le fait qu'in fine l'assembleur soit plus performant que du bon C++.

    Ceci dit, pour répondre à ta question, il n'est pas possible de mixer le paramètre template directement dans une chaîne de caractère (les deux traitements n'ont pas lieu au même moment lors de la compilation).

    La piste est probablement de générer les classes 'helper' (à la main ou avec Boost.Preprocessor si beaucoup), puis d'utiliser ton paramètre générique pour choisir la bonne. Boost.Preprocessor intervenant au moment du préprocessing peut aider à construire les chaînes de caractères adéquates en itérant sur un nombre de cas qui t'intéresse.

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Il n'y a pas de soucis pour le compilo, je ne suis vraiment pas fan de taper de l'assembleur. Mais le boss il écrit des packages pour boost, alors on compte les instructions, de plus ajouter un carry me pause pas mal de pb pour les signes des entiers.

    boost pp va fumer !

    ps: de plus je fais du gpu et l'assembleur de CUDA permet de faire des multiplications avec des propagations de carry bit (en hardware), (cette instruction n'existe pas en X86.

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Ce serait quelque chose de ce gout là peut être ?
    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
    #include <iostream>
    #include <boost/preprocessor/repetition/enum.hpp>
    #include <boost/preprocessor/stringize.hpp>
     
    template<int n> struct asm_helper;
    // ma répétition
    #define HELPER_ASM_MOVQ(z, n, dummy) \
       template<> struct asm_helper<n>\
       {\
          static void do_it()\
          {\
           std::cout<<"movq " BOOST_PP_STRINGIZE(0x08*n) "(%%rdi), %%r9" <<"\n";\
          }\
       };
     
    BOOST_PP_REPEAT(12, HELPER_ASM_MOVQ, d) 
     
     
    template<int n> void function()
    {
       asm_helper<n>::do_it();
    }
     
    int main()
    {
       function<1>();
       function<10>();
       return 0;
    }
    Y'a peut être mieux niveau Boost.PP. J'avoue ne pas forcément le connaitre sur le bout des doigts.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Ce serait quelque chose de ce gout là peut être ?
    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
    #include <iostream>
    #include <boost/preprocessor/repetition/enum.hpp>
    #include <boost/preprocessor/stringize.hpp>
     
    template<int n> struct asm_helper;
    // ma répétition
    #define HELPER_ASM_MOVQ(z, n, dummy) \
       template<> struct asm_helper<n>\
       {\
          static void do_it()\
          {\
           std::cout<<"movq " BOOST_PP_STRINGIZE(0x08*n) "(%%rdi), %%r9" <<"\n";\
          }\
       };
     
    BOOST_PP_REPEAT(12, HELPER_ASM_MOVQ, d) 
     
     
    template<int n> void function()
    {
       asm_helper<n>::do_it();
    }
     
    int main()
    {
       function<1>();
       function<10>();
       return 0;
    }
    Y'a peut être mieux niveau Boost.PP. J'avoue ne pas forcément le connaitre sur le bout des doigts.
    Wai t'es un deus !!!!! je ne connaissais pas BOOST_PP_STRINGIZE ça déchire comme solution !

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 9
    Points : 6
    Points
    6
    Par défaut petie update
    Hello, j'update ce post pour remercier tous les contributeurs . Grace à votre aide, j'ai pu faire une librairie de grand entier entièrement basée sur boost PP. Et bien avoir des bon speeds up par rapport à GMP. J'ai d'ailleurs fait un petit site vlilib.org

    Au plaisir,

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

Discussions similaires

  1. Tutoriels, F.A.Q : la rubrique Assembleur de Developpez.com
    Par Alcatîz dans le forum Assembleur
    Réponses: 3
    Dernier message: 07/06/2007, 20h14
  2. ecrire son OS (assembleur ??)
    Par Anonymous dans le forum Programmation d'OS
    Réponses: 9
    Dernier message: 25/11/2002, 20h25
  3. [XSLT] template
    Par demo dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 09/09/2002, 12h31
  4. Random en Assembleur
    Par funx dans le forum Assembleur
    Réponses: 9
    Dernier message: 02/09/2002, 18h05
  5. Quel désassembleur/assembleur pour un exe Windows ?
    Par Anonymous dans le forum x86 32-bits / 64-bits
    Réponses: 6
    Dernier message: 17/04/2002, 11h59

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