OpenMP 性能影响:私有指令与在构造内部声明变量
Posted
技术标签:
【中文标题】OpenMP 性能影响:私有指令与在构造内部声明变量【英文标题】:OpenMP Performance impact: private directive vs. declaring variable inside for construct 【发布时间】:2013-03-18 01:18:01 【问题描述】:在性能方面,以下哪个更有效?
在主线程中赋值并将值复制到所有线程:
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
初始化变量比将变量复制到所有线程要高效得多
【问题讨论】:
您是否尝试过测量,还是要求我们为您测量? 我没有测量它,但我不寻求数字的答案,我寻求更底层的答案。 如果您曾尝试测量它然后要求解释结果,这个问题会更有趣。 第一个版本不是有效的 OpenMP 代码。其他两个版本是等效的,很可能会导致为提取的 OpenMP 区域生成相同的汇编代码。 【参考方案1】:您提供的 3 个版本在性能方面没有太大差异,因为每个版本都使用 #pragma omp parallel for
。因此,OpenMP 会自动将每个迭代分配给不同的线程。因此,变量i
将成为每个线程的私有变量,并且每个线程将具有不同的迭代范围。变量'i'
自动设置为私有,以避免更新此变量时出现竞争条件。由于变量'i'
无论如何都将是私有的,因此无需将private(i) 放在#pragma omp parallel for
上。
尽管如此,您的第一个版本会产生错误,因为 OpenMP 期望 #pragma omp parallel for
正下方的循环具有以下格式:
for(init-expr; test-expr;incr-expr)
为了预先计算工作范围。
for 指令限制所有的结构 相关的 for 循环。具体来说,所有相关的 for 循环必须 具有以下规范形式:
for (init-expr; test-expr;incr-expr) 结构化块 (OpenMP Application Program Interface pag. 39/40.)
编辑:我测试了您的最后两个版本,并检查了生成的程序集。两个版本都生成相同的程序集,如您所见 -> version 2 和 version 3。
【讨论】:
以上是关于OpenMP 性能影响:私有指令与在构造内部声明变量的主要内容,如果未能解决你的问题,请参考以下文章