В ситуации, подобной следующей:
#pragma omp parallel
{
#pragma omp for
for(int ii = 0; ii < n; ii++) {
/* ... */
#pragma omp for
for(int jj = 0; jj < m; jj++) {
/* ... */
}
}
}
, что происходит, когда вы запускаете неопределенное поведение при нарушении стандарта OpenMP.Точнее, вы нарушаете ограничения, представленные в разделе 2.5 (конструкции разделения):
Следующие ограничения применяются к конструкциям разделения:
- Каждая область разделения должна встречаться всеми потоками.в команде или вообще ни при каких обстоятельствах.
- Последовательность встречающихся областей разделения и барьерных областей должна быть одинаковой для всех потоков в команде.
Это явнопоказано в примерах A.39.1c и A.40.1c :
Пример A.39.1c : следующий пример вложенности конструкции цикла соответствует, поскольку области внутреннего и внешнего цикла связываются с различными параллельными областями:
void work(int i, int j) {}
void good_nesting(int n)
{
int i, j;
#pragma omp parallel default(shared)
{
#pragma omp for
for (i=0; i<n; i++) {
#pragma omp parallel shared(i, n)
{
#pragma omp for
for (j=0; j < n; j++)
work(i, j);
}
}
}
}
Пример A.40.1c : Следующий пример не соответствует поскольку внутренние и внешние области цикла тесно вложены
void work(int i, int j) {}
void wrong1(int n)
{
#pragma omp parallel default(shared)
{
int i, j;
#pragma omp for
for (i=0; i<n; i++) {
/* incorrect nesting of loop regions */
#pragma omp for
for (j=0; j<n; j++)
work(i, j);
}
}
}
Обратите внимание, что это отличается от:
#pragma omp parallel for
for(int ii = 0; ii < n; ii++) {
/* ... */
#pragma omp parallel for
for(int jj = 0; jj < m; jj++) {
/* ... */
}
}
, в котором вы пытаетесь создать вложенную параллельную область.Только в этом случае обсуждение Мистического ответа имеет место.