У меня проблемы с определением, что происходит с этим примером задачи OpenMP. Для контекста y - это большой общий массив, а rowIndex не уникален для каждой задачи. Может быть несколько задач, пытающихся увеличить значение y [rowIndex].
Мой вопрос таков: нужно ли защищать условие сокращения или достаточно атомарного обновления? Я в настоящее время испытываю сбой с гораздо более крупной программой, и мне интересно, если я что-то не так с этим.
Из примеров, которые я видел, большинство сокращений массива предназначено для очень маленьких массивов из-за копирования массива для каждого потока, в то время как большинство атомарных обновлений не используются для элементов массива. Похоже, не так много контента для обновления общего массива по одному элементу за раз, что может привести к состоянию гонки (также редко встречается контекст параллелизма на основе задач).
#pragma omp parallel shared(y) // ??? reduction(+:y) ???
#pragma omp single
for(i = 0; i < n; i++)
{
sum = DoSmallWork_SingleThread();
rowIndex = getRowIndex_SingleThread();
#pragma omp task firstprivate(sum, rowIndex)
{
sum += DoLotsOfWork_TaskThread();
// ??? #pragma omp atomic update ???
y[ rowIndex ] += sum;
}
}