for ループに含まれるストリームを複数のストリームに分割します。
>>-#--pragma--stream_unroll--(--+---+--)----------------------->< '-n-'
ここで、n はループのアンロール係数です。C プログラムでは、 値 n は正の整数定数式です。C++ プログラムでは、値 n は正のスカラー整数またはコンパイル時定数の初期設定式です。 アンロール係数として 1 を指定すると、アンロールが使用不可になります。 n を指定しない場合、および -qhot、-qsmp、または -O4 以上が指定された場合は、最適化プログラムにより、それぞれのネストされたループごとに該当するアンロール係数が決定されます。
ストリーム・アンロールを使用可能にするには、-O3 でも -qipa=level=2 でも十分ではありません。さらに追加して -qhot または -qsmp を指定するか、あるいは最適化レベル -O4 以上を使用する必要があります。
ストリーム・アンロールを発生させるには、#pragma stream_unroll ディレクティブが for ループより前に指定された最後のプラグマでなければなりません。同じ for に対して #pragma stream_unroll を複数回指定したり、このプラグマを他のループ・アンロール・プラグマ (unroll、nounroll、unrollandfuse、 nounrollandfuse) と組み合わせて使用した場合も、XL C から警告が出されます。 XL C++ は、同じ for ループに指定された複数のループ・アンロール・プラグマのうち、最後のものを除くすべてのプラグマを、警告を出すことなく無視します。
#pragma stream_unroll の後に #pragma block_loop がある場合、ストリーム・アンロールは行われません。この状態でも、XL C はまた重大エラーを出します。 XL C++ では診断は出されませんが、最適化プログラムがストリーム・アンロール最適化を適用しない可能性があります。
ストリーム・アンロールは、特定の最適化オプションを指定してコンパイルを行った場合にも抑止されます。オプション -qstrict が有効な場合、ストリーム・アンロールは行われません。したがって、-qhot オプションのみでストリーム・アンロールを使用可能にしたい場合は、-qnostrict も指定する必要があります。
以下に、#pragma stream_unroll を使用してパフォーマンスを向上させる方法の例を示します。
アンロール係数 4 は、以下のように、反復の数を n から n/4 まで削減します。int i, m, n; int a[1000][1000]; int b[1000][1000]; int c[1000][1000]; .... #pragma stream_unroll(4) for (i=1; i<n; i++) { a[i] = b[i] * c[i]; }
for (i=1; i<n/4; i++) { a[i] = b[i] + c[i]; a[i+m] = b[i+m] + c[i+m]; a[i+2*m] = b[i+2*m] + c[i+2*m]; a[i+3*m] = b[i+3*m] + c[i+3*m]; }
読み取りおよび保管操作は数が増えると、コンパイラーによって決定された多数のストリーム間で分散され、計算時間が削減され、パフォーマンスが向上します。
関連参照