web-dev-qa-db-fra.com

Dites à gcc de dérouler spécifiquement une boucle

Comment puis-je dire à GCC de dérouler une boucle particulière? J'ai utilisé le SDK CUDA où les boucles peuvent être déroulées manuellement à l'aide de #pragma unroll. Existe-t-il une fonctionnalité similaire pour gcc? J'ai googlé un peu mais je n'ai rien trouvé.

46
Nils

GCC vous propose plusieurs façons de gérer cela:

  • Utilisez # directives pragma , comme #pragma GCC optimize ("string"...), comme vu dans les GCC docs . Notez que le pragma fait les optimisations global pour les fonctions restantes. Si vous avez utilisé #pragma Push_options et pop_options macros intelligemment, vous pourriez probablement définir cela autour d'une seule fonction comme ceci:

    #pragma GCC Push_options
    #pragma GCC optimize ("unroll-loops")
    
    //add 5 to each element of the int array.
    void add5(int a[20]) {
        int i = 19;
        for(; i > 0; i--) {
            a[i] += 5;
        }
    }
    
    #pragma GCC pop_options
    
  • Annoter les fonctions individuelles avec la syntaxe d'attribut de GCC : consultez les documents attribut de fonction GCC pour une dissertation plus détaillée sur le sujet. Un exemple:

    //add 5 to each element of the int array.
    __attribute__((optimize("unroll-loops")))
    void add5(int a[20]) {
        int i = 19;
        for(; i > 0; i--) {
            a[i] += 5;
        }
    }
    

Remarque: Je ne sais pas à quel point GCC est capable de dérouler les boucles à itération inverse (je l'ai fait pour que Markdown joue Nice avec mon code). Cependant, les exemples devraient compiler correctement.

54
Philip Conrad

-funroll-loops pourrait être utile (bien qu'il active le déroulement de boucle globalement, pas par boucle). Je ne sais pas s'il y a un #pragma Faire la même chose...

4
Jerry Coffin

GCC 8 a acquis un nouveau pragma qui vous permet de contrôler la façon dont le déroulement de la boucle est effectué:

#pragma GCC unroll n

Citant du manuel:

Vous pouvez utiliser ce pragma pour contrôler le nombre de fois qu'une boucle doit être déroulée. Il doit être placé immédiatement avant une boucle for, while ou do ou un ivdep #pragma GCC, et s'applique uniquement à la boucle qui suit. n est une expression constante entière spécifiant le facteur de déroulement. Les valeurs de 0 et 1 bloquent tout déroulement de la boucle.

4
Frederik Deweerdt