'var': OpenMP 'for' ループのインデックス変数は、ループ ボディで変更できません
OpenMP for
ループでは、for
ループの本体のインデックス (ループ カウンター) を変更できない場合があります。
次の例では C3020 が生成されます。
// C3020.cpp
// compile with: /openmp
int main() {
int i = 0, n = 3;
#pragma omp parallel
{
#pragma omp for
for (i = 0; i < 10; i += n)
i *= 2; // C3020
// try the following line instead
// n++;
}
}
lastprivate で宣言された変数は、並列化されたループ内のインデックスとして使用できません。
次の例では、2 番目の lastprivate に C3020 を指定します。これは、その lastprivate が最も外側の for ループ内の idx_a への書き込みをトリガーするためです。 最初の lastprivate は、最も外側の for ループの外側 (技術的には、最後の反復の最後) で idx_a への書き込みをトリガーするため、エラーは発生しません。 次の例では C3020 が生成されます。
// C3020b.cpp
// compile with: /openmp /c
float a[100][100];
int idx_a, idx_b;
void test(int first, int last)
{
#pragma omp parallel for lastprivate(idx_a)
for (idx_a = first; idx_a <= last; ++idx_a) {
#pragma omp parallel for lastprivate(idx_a) // C3020
for (idx_b = first; idx_b <= last; ++idx_b) {
a[idx_a][idx_b] += 1.0f;
}
}
}
次の例では、考えられる解決策を示しています。
// C3020c.cpp
// compile with: /openmp /c
float a[100][100];
int idx_a, idx_b;
void test(int first, int last)
{
#pragma omp parallel for lastprivate(idx_a)
for (idx_a = first; idx_a <= last; ++idx_a) {
#pragma omp parallel for lastprivate(idx_b)
for (idx_b = first; idx_b <= last; ++idx_b) {
a[idx_a][idx_b] += 1.0f;
}
}
}