Используйте предложение #pragma omp parallel for reduction(+:a)
перед циклом for
Переменная
, объявленная в цикле for
, является локальной, а также счетчиками цикла
переменные, объявленные вне блока #pragma omp parallel
, являются общими по умолчанию, если не указано иное (см. пункты shared
, private
, firstprivate
). Следует соблюдать осторожность при обновлении общих переменных, так как может возникнуть состояние гонки.
В этом случае предложение reduction(+:a)
указывает, что a
является общей переменной, для которой выполняется сложение в каждом цикле. Потоки будут автоматически отслеживать общую сумму, которую нужно добавить, и безопасно увеличивать a в конце цикла.
Оба кода ниже эквивалентны:
float a = 0.0f;
int n=1000;
#pragma omp parallel shared(a) //spawn the threads
{
float acc=0; // local accumulator to each thread
#pragma omp for // iterations will be shared among the threads
for (int i = 0; i < n; i++){
float x = algorithm(i); //do something
acc += x; //local accumulator increment
} //for
#omp pragma atomic
a+=acc; //atomic global accumulator increment: done on thread at a time
} //end parallel region, back to a single thread
cout << a;
Эквивалентно:
float a = 0.0f;
int n=1000;
#pragma omp parallel for reduction(+:a)
for (int i = 0; i < n; i++){
int x = algorithm(i);
a += x;
} //parallel for
cout << a;
Обратите внимание, что вы не можете создать цикл for с условием остановки i<x
, где x
- локальная переменная, определенная в цикле.