C++ 嵌套循环OpenMP并行化,私有还是公共索引?
假设在平行区域中有一个嵌套的循环,类似于:C++ 嵌套循环OpenMP并行化,私有还是公共索引?,c++,c,for-loop,parallel-processing,openmp,C++,C,For Loop,Parallel Processing,Openmp,假设在平行区域中有一个嵌套的循环,类似于: #pragma omp parallel { for (int i = 0, ...) { for (int j = 0, ...) { }}} 或 如果使用#pragma omp for,i索引将自动变为私有索引。但是我们需要将j指数设置为私有还是公共?效果如何 #pragma omp parallel { #pragma omp for shared(j) for (int i = 0, ...)
#pragma omp parallel
{
for (int i = 0, ...) {
for (int j = 0, ...) { }}}
或
如果使用#pragma omp for,i索引将自动变为私有索引。但是我们需要将j指数设置为私有还是公共?效果如何
#pragma omp parallel
{
#pragma omp for shared(j)
for (int i = 0, ...) {
for (int j = 0, ...) { }}}
或
提前谢谢 在平行区域内宣布的一切都是自动私有的。这(大概)就是您想要的行为:
i
的每次迭代都应该循环通过所有j
,而j
循环都是独立的(因此是私有的,而不是公共的)。然而,实际上您缺少重要的并行部分:如果您不编写
#pragma omp parallel for
但只是
#pragma omp for
这样,您就不会并行地发生任何事情(除非您首先在封闭范围内使用#pragma omp parallel
创建了一个并行区域) Private j不起作用,因为默认情况下j是Private的(因为它在i for循环中的作用域,所以当创建新线程时,j特定于该线程)
#pragma omp parallel for private(j)
for (int i = 0, ...) {
for (int j = 0, ...) { }}
如果您使用shared j
它应该没有如上所述的效果,因为j的作用域对于i的每个实例都是局部的,如果您将j的作用域扩展到全局,您将遇到一个种族编码什么?这是用于循环的并行化!!对于for循环,您可以使用pragma omp parallel{}或pragma omp for without{}!!#pragma-omp-for
也可以使用,只是它需要被#pragma-omp-parallel
区域封装。在您提到的链接页面中:“指令omp-for
指示编译器在遇到此工作共享构造的线程团队中分配循环迭代。”。该线程组是由parallel
OpenMP构造创建的。@alienflow是。但除非您处于并行区域,否则它不会做任何事情。@DanielLangr我在编辑中更明确地指出了这一点,谢谢。因此,对于I private和j shared,我将具有竞争条件?如果j具有全局作用域,则是,如果j在本地声明为no race cond遗嘱occur@alienflow您不能将j
设置为shared,因为它在并行区域的作用域中未定义。因此没有竞争条件,只有编译器错误(对于任何sane编译器)。
#pragma omp parallel
{
#pragma omp for private(j)
for (int i = 0, ...) {
for (int j = 0, ...) { }}}
#pragma omp parallel for private(j)
for (int i = 0, ...) {
for (int j = 0, ...) { }}