Udostępnij za pomocą


Błąd kompilatora C3020

"var": zmienna indeksu pętli OpenMP "for" nie może być modyfikowana w treści pętli

Uwagi

Pętla OpenMP for może nie modyfikować indeksu (licznika pętli) w treści for pętli.

Przykłady

Poniższy przykład generuje kod 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++;
   }
}

Zmienna zadeklarowana za pomocą lastprivate nie może być używana jako indeks wewnątrz pętli równoległej.

Poniższy przykład daje C3020 dla drugiego lastprivate, ponieważ ten lastprivate wyzwoli zapis w celu idx_a w obrębie pętli najbardziej zewnętrznej dla pętli. Pierwszy element lastprivate nie daje błędu, ponieważ funkcja lastprivate wyzwala zapis w celu idx_a poza najbardziej zewnętrzną pętlą (technicznie na samym końcu ostatniej iteracji). Poniższy przykład generuje kod 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;
      }
   }
}

W poniższym przykładzie pokazano możliwe rozwiązanie:

// 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;
      }
   }
}