10.102 #pragma unroll [(n)]

このプラグマによって、コンパイラに n 回の繰り返しによるループの展開を指示します。

ベクトル化されたループもベクトル化されていないループも、どちらも #pragma unroll [(n)] を使用して展開できます。つまり、#pragma unroll [(n)] は、 --vectorize--no_vectorize の両方に適用されます。

構文

#pragma unroll
#pragma unroll (n)
各項目には以下の意味があります。
n
展開のための繰り返し回数を示すオプション値です。

デフォルト

n の値を指定しない場合は、#pragma unroll (4) が仮定されます。

使用法

このプラグマは、-O3 -Otime でコンパイルする場合にのみ適用されます。-O3 -Otime を使用してコンパイルする場合、ループの展開が有効な場所では自動的にループが展開されます。このプラグマを使用すると、自動的に展開されないループの展開をコンパイラに要求できます。

このプラグマは、コンパイラによって最適なループの展開が行われていないという確証が --diag_warning=optimizations などから得られる場合にのみ使用します。
このプラグマによって何らかの効果が得られたかどうかは、実際に --diag_warning=optimizations でコンパイルするか、生成されたアセンブリコードを検証したときに初めて判別できます。その両方が必要になる場合もあります。

制約条件

このプラグマは -O3 -Otime でコンパイルした場合にのみ効果があります。また、このプラグマは、自動的には展開されなかったループを展開するための、あくまでもコンパイラへの要求です。必ずしもループが展開されるとは限りません。
#pragma unroll [(n)] は、 for ループ、 while ループ、または do ... while ループの直前でのみ使用できます。

void matrix_multiply(float ** __restrict dest, float ** __restrict src1,
    float ** __restrict src2, unsigned int n)
{
    unsigned int i, j, k;
    for (i = 0; i < n; i++)
    {
        for (k = 0; k < n; k++)
        {
            float sum = 0.0f;
            /* #pragma unroll */
            for(j = 0; j < n; j++)
                sum += src1[i][j] * src2[j][k];
            dest[i][k] = sum; 
        }
    }
}
このサンプルでは、 src2src2[j][k] としてインデクスされ、ループが逆の順序すなわち jk の内側にネストされているので、コンパイラによるループ解析は正常に完了しません。このサンプルの #pragma unroll のコメント化を解除すると、ループは 4 回展開されます。
n * n のマトリクスのようなサイズが 4 の倍数でないマトリクスを掛けることが目的であれば、代わりに #pragma unroll (m) を使用できます。ここで、 m は、 n m の整数倍であるような値です。
関連する概念
5.7 C コードのループの展開
関連する参考文書
10.103 #pragma unroll_completely
8.62 --diag_warning=tag[,tag,...]
8.139 -Onum
8.144 -Otime
8.192 --vectorize、--no_vectorize
非機密扱いPDF file icon PDF 版ARM DUI0472LJ
Copyright © 2010-2015 ARM.All rights reserved.