2009-09-19 41 views
74

的是这两者之间的区别?OMP并行与OMP并行的

[A]

#pragma omp parallel 
{ 
    #pragma omp for 
    for(int i = 1; i < 100; ++i) 
    { 
     ... 
    } 
} 

[B]

#pragma omp parallel for 
for(int i = 1; i < 100; ++i) 
{ 
    ... 
} 

回答

50

我不认为有任何差异,一个是为其他的快捷方式。尽管你的确切实现可能会以不同的方式处理

将合并的并行工作共享构建体是用于 快捷方式指定包含一个工作共享构造 并行构造和其它语句。允许的条款是允许并行和工作共享contructs条款 的工会。

http://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdf

采取表示OpenMP的规格在这里:

http://openmp.org/wp/openmp-specifications/

44

这些是等价的。

#pragma omp parallel产生了一组线程,而#pragma omp for划分了产生的线程之间的循环迭代。您可以使用融合的#pragma omp parallel for指令一次完成这两件事。

+0

在我的代码中,我正在使用这个结构。但是,当我在for指令中使用'schedule(static,chunk)'子句时,我遇到了一个问题。代码运行良好,但是当我从MPI程序调用此代码时,它会运行到无限循环。循环计数器在此循环的所有迭代中都为零。我在'#pragma omp parallel'指令中将循环计数器定义为private。不知道为什么它只在MPI调用代码时失败。我确信每个MPI进程都在群集的不同处理器上运行(如果有的话)。不知道日程安排是否会导致问题。 – 2011-10-03 02:29:03

+0

当我使用'#pragma omp parallel for'指令时,同样的事情可以正常工作。应该有一些区别。 – 2011-10-03 02:30:16

+1

更新:事实证明,我只在使用schedule子句时才观察到这个问题,所以我猜这不取决于我是使用组合并行还是两个不同的指令。 – 2011-10-03 19:52:07

2

我看到截然不同的运行时,当我采取一个for循环以g ++ 4.7.0 和使用

std::vector<double> x; 
std::vector<double> y; 
std::vector<double> prod; 

for (int i = 0; i < 5000000; i++) 
{ 
    double r1 = ((double)rand()/double(RAND_MAX)) * 5; 
    double r2 = ((double)rand()/double(RAND_MAX)) * 5; 
    x.push_back(r1); 
    y.push_back(r2); 
} 

int sz = x.size(); 

#pragma omp parallel for 

for (int i = 0; i< sz; i++) 
    prod[i] = x[i] * y[i]; 

串行代码(没有openmp)运行在79毫秒。 “并行”代码在29 ms内运行。 如果我省略了for和使用#pragma omp parallel,运行时拍摄到179ms, 比串行代码慢。 (本机具有的8 HW并发)

代码链接到libgomp

+2

我认为这是因为omp parallel在单独的线程中执行循环而没有将其分成线程,所以主线程正在等待第二个线程完成。并花费在同步上。 – Antigluk 2012-10-24 15:38:08

+6

这是因为没有'#pragma omp for',根本没有多线程共享循环。但是,这不是OPs的情况,请在'#pragm omp parallel'内再次使用'#pragma omp for'来尝试再次运行,它应该像'#pragma omp parallel for'版本一样运行(如果不是相同的话) 。 – 2013-10-14 15:27:36

+0

我认为这个答案是最好的答案,因为它表明它们不是“等价的” – 2017-03-25 09:45:33

19

下面是实施例的使用分离parallelforhere。简而言之,它可用于在几个线程中执行for周期之前动态分配OpenMP线程专用阵列。 这是不可能做同样的初始化中parallel for情况。

UPD: 在问题例如有单个编译和两个编译指示之间无差异。但在实践中,您可以使用分离的并行和指令使线程感知更多的行为。 例如有些代码:

#pragma omp parallel 
{ 
    double *data = (double*)malloc(...); // this data is thread private 

    #pragma omp for 
    for(1...100) // first parallelized cycle 
    { 
    } 

    #pragma omp single 
    {} // make some single thread processing 

    #pragma omp for // second parallelized cycle 
    for(1...100) 
    { 
    } 

    #pragma omp single 
    {} // make some single thread processing again 

    free(data); // free thread private data 
} 
4

虽然具体例子的两个版本是等价的,在其他的答案已经提到的,它们之间还是一个小的差异。第一个版本包含一个不必要的隐含屏障,在“omp for”结尾处遇到。另一个隐式屏障可以在并行区域的末尾找到。将“nowait”添加到“omp for”会使两个代码等效,至少从OpenMP的角度来看。我提到这是因为OpenMP编译器可能会为这两种情况生成稍微不同的代码。