1.7.4. ivdep プラグマを使用したループ伝搬依存性の削除
ループ依存性に関する詳細は、safelen(N)クローズをivdepプラグマに追加することで取得できます。safelen(N)クローズはループ伝搬依存性のない連続ループ反復の最大数を指定します。例えば、#pragma ivdep safelen(32)はコンパイル時にループ伝搬依存性が導入される前に最大 32 回のループ反復があることをコンパイラーに示します。つまり、#pragma ivdepはこのループの反復間に暗黙的なメモリー依存性がないことを保証し、#pragma safelen(32)はこの反復に依存する可能性のある最も近い反復が 32 回の反復であることを保証します。
ループ内部の特定のメモリーアレイへのアクセスがループ伝搬依存性を引き起こさないように指定するには、コンポーネント・コードのループの前に#pragma ivdep array (array_name)行を追加します。ivdepプラグマで指定されたアレイは、ローカルまたはプライベートのメモリーアレイ、もしくはグローバル、ローカル、またはプライベートのメモリーストレージを指すポインター変数でなければなりません。指定されたアレイがポインターの場合、ivdepプラグマは指定されたポインターでエイリアスする可能性があるすべてのアレイにも適用されます。ivdepプラグマで指定されたアレイは、構造体のアレイまたはポインターメンバーでもあります。
使用ケース 1:
ループ内部のメモリーアレイへのすべてのアクセスがループ伝搬依存性を引き起こさない場合、ループの前に#pragma ivdepを追加します。
1 // no loop-carried dependencies for A and B array accesses
2 #pragma ivdep
3 for(int i = 0; i < N; i++) {
4 A[i] = A[i + N];
5 B[i] = B[i + N];
6 }
使用ケース 2:
#pragma ivdep array (array_name)はすべてのアレイアクセスに代わり、特定のメモリーアレイに指定できます。このプラグマはアレイ、ポインター、または構造体のポインターメンバーに適用されます。指定したアレイがポインターの場合、ivdepプラグマは指定したポインターでエイリアスする可能性のあるすべてのアレイに適用します。
1 // No loop-carried dependencies for A array accesses
2 // Compiler inserts hardware that reinforces dependency constraints for B
3 #pragma ivdep array(A)
4 for(int i = 0; i < N; i++) {
5 A[i] = A[i - X[i]];
6 B[i] = B[i - Y[i]];
7 }
8
9 // No loop-carried dependencies for array A inside struct
10 #pragma ivdep array(S.A)
11 for(int i = 0; i < N; i++) {
12 S.A[i] = S.A[i - X[i]];
13 }
14
15 // No loop-carried dependencies for array A inside the struct pointed by S
16 #pragma ivdep array(S->X[2][3].A)
17 for(int i = 0; i < N; i++) {
18 S->X[2][3].A[i] = S.A[i - X[i]];
19 }
20
21 // No loop-carried dependencies for A and B because ptr aliases
22 // with both arrays
23 int *ptr = select ? A : B;
24 #pragma ivdep array(ptr)
25 for(int i = 0; i < N; i++) {
26 A[i] = A[i - X[i]];
27 B[i] = B[i - Y[i]];
28 }
29
30 // No loop-carried dependencies for A because ptr only aliases with A
31 int *ptr = &A[10];
32 #pragma ivdep array(ptr)
33 for(int i = 0; i < N; i++) {
34 A[i] = A[i - X[i]];
35 B[i] = B[i - Y[i]];
36 }