web-dev-qa-db-ja.com

ループを具体的に展開するようにgccに指示する

特定のループを展開するようにGCCに指示するにはどうすればよいですか? #pragma unrollを使用してループを手動で展開できるCUDA SDKを使用しました。 gccに同様の機能はありますか?私は少しグーグルで検索しましたが、何も見つかりませんでした。

46
Nils

GCCは、これを処理するいくつかの異なる方法を提供します。

  • GCC docs に見られるように、#pragma GCC optimize ("string"...)のような#pragma directivesを使用します。プラグマは、残りの関数の最適化globalを行うことに注意してください。 #pragma Push_optionsおよびpop_optionsマクロを巧みに使用した場合、おそらく次のように1つの関数のみでこれを定義できます。

    #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
    
  • 個々の関数にGCCの属性構文で注釈を付けます: GCC function attribute docsで主題に関する詳細な論文を確認します。例:

    //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;
        }
    }
    

注:GCCが逆反復ループの展開にどれほど優れているかわかりません(MarkdownにコードでNiceを再生させるようにしました)。ただし、サンプルは正常にコンパイルされるはずです。

54
Philip Conrad

-funroll-loopsが役立つ場合があります(ただし、ループごとではなく、グローバルにループ展開を有効にします)。同じことをする#pragmaがあるかどうかわかりません...

4
Jerry Coffin

GCC 8には、ループの展開方法を制御できる新しいプラグマが追加されました。

#pragma GCC unroll n

マニュアルから引用:

このプラグマを使用して、ループを展開する回数を制御できます。 for、while、doループ、または#pragma GCC ivdepの直前に配置する必要があり、後続のループにのみ適用されます。 nは、展開係数を指定する整数定数式です。 0と1の値は、ループの展開をブロックします。

4