不同机器中不同的OpenMP输出

时间:2015-01-30 11:27:47

标签: openmp

当我试图在我的系统centos中运行以下代码时,我正在获得正确的输出,但是当我试图在紧凑型超级计算机“Param Shavak”上运行相同的代码时,我得到的输出不正确....: (

#include<stdio.h>
#include<omp.h>
int main()
{
  int p=1,s=1,ti
  #pragma omp parallel private(p,tid)shared(s)    
  {
    p=1;
    tid=omp_get_thread_num();    
    p=p+tid;    
    s=s+tid;    
    printf("Thread %d P=%d S=%d\n",tid,p,s);    
  }    
  return 0;    
}

1 个答案:

答案 0 :(得分:0)

如果你的程序在一台机器上正确运行,那一定是因为它实际上并没有在那台机器上并行运行。

您的程序在s=s+tid;代码行中遇到竞争条件。 s是一个共享变量,因此多个线程同时尝试更新它,这会导致数据丢失。

您可以通过将该行代码转换为原子操作来解决问题:

#pragma omp atomic
 s=s+tid;

这样一次只有一个线程可以读取和更新变量s,并且竞争条件不再存在。

在更复杂的程序中,您应该仅在必要时使用原子操作或关键区域 ,因为您在这些区域中没有并行性并且会损害性能。

编辑:正如用户高性能标记所建议的那样,我必须注意上面的程序由于原子操作而效率很低。进行这种计算的正确方法(在循环的所有迭代中添加相同的变量)是实现减少。通过使用reduction子句,OpenMP使其变得简单:

#pragma omp reduction(operator : variables)

尝试此版本的程序,使用还原:

#include<stdio.h>
#include<omp.h>
int main()
{
     int p=1,s=1,tid;
     #pragma omp parallel reduction(+:s) private(p,tid)
     {
          p=1;
          tid=omp_get_thread_num();
          p=p+tid;
          s=s+tid;
          printf("Thread %d P=%d S=%d\n",tid,p,s);
     }
     return 0;
}

以下链接以更详细的方式解释关键部分,原子操作和缩减:http://www.lindonslog.com/programming/openmp/openmp-tutorial-critical-atomic-and-reduction/