私有子句中的变量与OpenMP中并行区域中定义的变量之间是否存在任何差异?
我想知道是否有任何理由更喜欢OpenMP中的private(var)
子句超过(私有)变量的本地定义,例如
int var; #pragma omp parallel private(var) { ... }
与
#pragma omp parallel { int var; ... }
另外,我想知道私人条款的重点是什么。 这个问题已在OpenMP中解释过:局部变量是否自动私有? ,但我确信答案是错的 我不喜欢答案,因为即使C89不阻止你在函数中间定义变量,只要它们在作用域的开头(这是自动的输入并行区域时的情况)。 因此,即使对于老式的C程序员来说,这也不应该有任何区别。 我是否应该将其视为语法糖,它允许在过去的好日子里使用“定义变量 – 在你的function中开始”的风格?
顺便说一下:在我看来,第二个版本也阻止程序员在并行区域之后使用私有变量,希望它可能包含一些有用的东西,所以另一个-1用于private子句。
但是因为我对OpenMP很陌生,所以如果没有对它进行很好的解释,我不想怀疑它。 提前谢谢你的答案!
这不仅仅是语法糖。 OpenMP的一个特性是,如果代码未使用OpenMP编译,则不会更改串行代码。 如果不使用OpenMP进行编译,则忽略用作编译指示一部分的任何构造。 这样做可以parallel for
不更改代码的情况下使用private
, firstprivaate
, collapse
和parallel for
。 更改代码可能会影响编译器如何优化代码。
如果你有像这样的代码
int i,j; #pragma omp parallel for private(j) for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { } }
在C89
没有private
的唯一方法是通过在并行部分中定义j
来更改代码,例如:
int i,j; #pragma omp parallel { int j; #pragma omp for for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { } } }
这是一个带有firstprivate
的C ++示例。 假设你有一个你想要私有的向量。 如果您使用firstprivate
,则不必更改代码,但如果在并行区域内声明私有副本,则会更改代码。 如果在没有OpenMP的情况下编译它,则会生成不必要的副本。
vector a; #pragma omp parallel { vector a_private = a; }
此逻辑适用于许多其他构造。 例如collapse
。 您可以手动融合一个更改代码的循环,或者您可以使用collapse
并仅在使用OpenMP编译时融合它。
但是,尽管如此,实际上我经常发现我需要更改代码才能获得最佳的并行结果,所以我通常会在并行部分中定义所有内容,并且不使用private
, firstprivate
或collapse
(更不用说C ++中的OpenMP实现经常与非POD斗争,所以通常自己做得更好)。