OpenMP性能影响:私有指令与构造内部声明变量

时间:2013-03-18 01:18:01

标签: c++ multithreading performance parallel-processing openmp

性能方面,以下哪项更有效?

在主线程中分配并将值复制到所有线程:

int i = 0;
#pragma omp parallel for firstprivate(i)
for( ; i < n; i++){
    ...
}

在每个线程中声明并分配变量

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

在主线程中声明变量,但在每个线程中分配它。

int i;
#pragma omp parallel for private(i)
for(i = 0; i < n; i++){
    ...
}

这似乎是一个愚蠢的问题和/或性能影响可以忽略不计。但是我正在并行化一个执行少量计算的循环,并且被称为大量次数,因此我可以从这个循环中挤出的任何优化都是有帮助的。

我正在寻找更低级别的解释以及OpenMP如何处理这个问题。

例如,如果对大量线程进行并行化,我假设第二个实现会更有效,因为使用xor初始化变量比将变量复制到所有线程更有效

1 个答案:

答案 0 :(得分:4)

您提供的3个版本在性能方面没有太大差异,因为每个版本都使用#pragma omp parallel for。因此,OpenMP会自动将每个迭代分配给不同的线程。因此,变量i将变为每个线程的私有,并且每个线程将具有不同的迭代范围以供使用。变量'i'自动设置为private,以便在更新此变量时避免竞争条件。因为变量'i'在并行上是私有的,所以不需要在#pragma omp parallel for上放置 private(i)

然而,您的第一个版本会产生错误,因为OpenMP期望#pragma omp parallel for下面的循环具有以下格式:

for(init-expr; test-expr;incr-expr)

为了预先计算工作范围。

  

for指令对所有结构设置了限制   相关的for循环。具体来说,所有相关的for循环必须   具有以下规范形式:

     

for(init-expr; test-expr; incr-expr)structured-block(OpenMP Application Program Interface pag.39 / 40。)

编辑:我测试了您的最后两个版本,并检查了生成的程序集。如您所见,两个版本都生成相同的程序集 - &gt; version 2version 3