Глядя на документ здесь , следующая конструкция хорошо определена:
#pragma omp parallel //Line 1
{
#pragma omp for nowait //Line 3
for (i=0; i<N; i++)
a[i] = // some expression
#pragma omp for //Line 6
for (i=0; i<N; i++)
b[i] = ...... a[i] ......
}
, поскольку
Здесь предложение nowait подразумевает, что потоки могут запускатьсяво втором цикле, в то время как другие потоки все еще работают над первым.Поскольку оба цикла используют здесь одно и то же расписание, итерация, использующая [i], может действительно полагаться на то, что это значение было вычислено.
Мне трудно понять, почему это так.Предположим, что Line 3
были:
#pragma omp for
тогда, так как непосредственно перед Line 6
существует неявный барьер, следующий цикл for будет иметь значения при всех индексах a
полностьювычислен.Но с no wait
в Line 3
как это будет работать?
Предположим, Line 1
запускает 4 потока, t1, t2, t3
и t4
.Предположим, что N
равно 8, а разбиение индексов в первом цикле for таково:
t1: 0, 4
t2: 1, 5
t3: 2, 6
t4: 3, 7
Предположим, t1
сначала завершает индексы 0
и 4
и получает Line 6
Чтоточно сейчас происходит?Как гарантируется, что теперь он будет работать с теми же индексами 0
и 4
, для которых значения a
правильно вычислены им на предыдущей итерации?Что если второй for
цикл обращается к a[i+1]
?