編譯器錯誤 C3020
'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 宣告的變數不能當做平行化迴圈內的索引使用。
下列範例會為第二個 lastprivate 提供 C3020,因為 lastprivate 會觸發寫入至最外層 for 迴圈內的idx_a。 第一個 lastprivate 不會提供錯誤,因為 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;
}
}
}