2013-05-13 7 views
2

У меня есть этот фрагмент кода, который распараллелен.Каково использование сокращения в openmp?

int i,n; double area,pi,x; 
area=0.0; 
#pragma omp parallel for private(x) reduction (+:area) 
for(i=0; i<n; i++){ 
x= (i+0.5)/n; 
area+= 4.0/(1.0+x*x); 
} 
pi = area/n; 

Говорят, что сокращение устраняет состояние гонки, которое может произойти, если мы не использовали сокращение. Тем не менее, мне интересно, нужно ли добавлять lastprivate для области, поскольку она используется вне параллельного цикла и не будет видна за ее пределами. Else делает это сокращение также?

+0

Вы не хотите использовать последний закрытый. Прочитайте эту ссылку, чтобы узнать о сокращениях, firstprivate, lastprivate и других вещах в OpenMP http://bisqwit.iki.fi/story/howto/openmp/#ReductionClause. См. Мой ответ для получения дополнительной информации о сокращениях. –

ответ

0

Reduction заботится о том, чтобы сделать частную копию area для каждой темы. Как только площадь конца параллельной области уменьшается в одной атомной операции. Другими словами, обнажаемый area представляет собой совокупность всех частных area s каждого потока.

thread 1 - private area = compute(x) 
thread 2 - private area = compute(y) 
thread 3 - private area = compute(z) 

reduction step - public area = area<thread1> + area<thread2> + area<thread3> ... 
+0

Спасибо. Итак, pi получает правильное значение, а не 0? Я думал, что значения, определенные за пределами параллельных секций, потеряют значение вне цикла, если не определено как lastprivate. – MadHatter

0

Не требуется lastprivate. Чтобы помочь вам понять, как это делается, я думаю, что полезно посмотреть, как это можно сделать с помощью atomic. Следующий код

float sum = 0.0f; 
pragma omp parallel for reduction (+:sum) 
for(int i=0; i<N; i++) { 
    sum += // 
} 

эквивалентно

float sum = 0.0f; 
#pragma omp parallel 
{ 
    float sum_private = 0.0f; 
    #pragma omp for nowait 
    for(int i=0; i<N; i++) { 
     sum_private += // 
    } 
    #pragma omp atomic 
    sum += sum_private; 
} 

Хотя этот вариант имеет больше кода полезно, чтобы показать, как использовать более сложные операторы. Одно ограничение при подаче заявки reduction заключается в том, что atomic поддерживает только несколько основных операторов. Если вы хотите использовать более сложный оператор (например, дополнение SSE/AVX), вы можете заменить atomic на criticalreduction with OpenMP with SSE/AVX

Смежные вопросы