#pragma unrollandfuse

説明

このプラグマはネストされた for ループに対してアンロールおよびフューズ操作を試行するようコンパイラーに命令します。

構文

構文図を読む構文図をスキップする>>-#--pragma--+-nounrollandfuse------------+-------------------><
              '-unrollandfuse--(--+---+--)-'
                                  '-n-'
 

ここで、n はループのアンロール係数です。C プログラムでは、n の値は正の整数定数式です。C++ プログラムでは、n の値は正のスカラー整数またはコンパイル時の定数初期化式です。 n が指定されておらず、 -qhot-qsmpまたは -O4 以上が指定されている場合は、最適化プログラムはそれぞれネストされたループごとに適切なアンロール係数を判別します。

#pragma unrollandfuse ディレクティブは、以下の条件を満たすネストされた for ループ構造体の外部ループのみに適用されます。

ループのアンロールが発生するためには、#pragma unrollandfuse ディレクティブが for ループに先行している必要があります。最も内部の for ループに対して #pragma unrollandfuse を指定することはできません。

同じ for ループに対して #pragma unrollandfuse を複数回指定したり、このディレクティブを nounrollandfusenounrollunroll、または stream_unroll ディレクティブと結合しないでください。

#pragma nounrollandfuse を指定すると、そのループをアンロールしないようコンパイラーに命令します。

  1. 以下の例では、#pragma unrollandfuse ディレクティブはループの本体を複製して、フューズしています。これにより、配列 b に対するキャッシュの欠落の数が削減されます。
    int i, j;
    int a[1000][1000];
    int b[1000][1000];
    int c[1000][1000];
    
    
    ....
    
    #pragma unrollandfuse(2)
    for (i=1; i<1000; i++) {
        for (j=1; j<1000; j++) {
            a[j][i] = b[i][j] * c[j][i];
        }
    }
    
    以下の for ループは、#pragma unrollandfuse(2) ディレクティブを上記のループ構造体に適用した場合の可能な結果を示しています。
    for (i=1; i<1000; i=i+2) {
        for (j=1; j<1000; j++) {
            a[j][i] = b[i][j] * c[j][i];
            a[j][i+1] = b[i+1][j] * c[j][i+1];
        }
    }
    
  2. また、ネストされたループ構造体に複数の #pragma unrollandfuse ディレクティブを指定することもできます。
    int i, j, k;
    int a[1000][1000];
    int b[1000][1000];
    int c[1000][1000];
    int d[1000][1000];
    int e[1000][1000];
    
    
    ....
    
    #pragma unrollandfuse(4)
    for (i=1; i<1000; i++) {
    #pragma unrollandfuse(2)
        for (j=1; j<1000; j++) {
    			for (k=1; k<1000; k++) {
                a[j][i] = b[i][j] * c[j][i] + d[j][k] * e[i][k];
            }
        }
    }
    

関連情報