for循环openmp中的局部变量

时间:2018-11-07 10:00:15

标签: c++ for-loop openmp

我刚刚开始使用openmp进行编程,我正在尝试将for循环与需要循环外的变量并行化。像这样:

float a = 0;
for (int i = 0; i < x; i++)
{
    int x = algorithm();
    /* Each loop, x have a different value*/
    a = a + x;
}
cout << a;

我认为变量a必须是每个线程的局部变量。这些线程结束工作后,应将所有局部变量a添加到一个最终结果中。

我该怎么做?

3 个答案:

答案 0 :(得分:3)

有许多机制可以实现您的目标,但是最简单的方法是采用OpenMP并行缩减:

float a = 0.0f;
#pragma omp parallel for reduction(+:a)
for(int i = 0; i < x; i++) 
  a += algorithm();
cout << a;

答案 1 :(得分:2)

在for循环之前使用#pragma omp parallel for reduction(+:a)子句

for循环中声明的

变量是局部变量以及循环计数器 除非另有说明,否则在#pragma omp parallel块外部声明的变量是默认共享的(请参见sharedprivatefirstprivate子句)。更新共享变量时应格外小心,因为可能会出现竞争状况。 在这种情况下,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;

请注意,您无法在停止条件为i<x的情况下进行for循环,其中x是在循环内定义的局部变量。

答案 2 :(得分:0)

由于更新是标量关联的,因此可以使用以下结构对线程专用容器执行并行缩减。

float a = 0;//Global and will be shared.
#pragma omp parallel 
{
    float y = 0;//Private to each thread
#pragma omp for
    for(int i = 0; i < x; i++)
         y += algorithm();//Better practice is to not use same variable as loop termination variable.
//Still inside parallel
#pragma omp atomic
    a += y;
 }
cout << a;