gpt4 book ai didi

c++ - 使用 OpenMP 并行化 C++ 代码,并行计算实际上更慢

转载 作者:太空狗 更新时间:2023-10-29 20:36:39 30 4
gpt4 key购买 nike

我有以下要并行化的代码:

int ncip( int dim, double R)
{
int i;
int r = (int)floor(R);
if (dim == 1)
{
return 1 + 2*r;
}
int n = ncip(dim-1, R); // last coord 0

#pragma omp parallel for
for(i=1; i<=r; ++i)
{
n += 2*ncip(dim-1, sqrt(R*R - i*i) ); // last coord +- i
}

return n;
}

在没有 openmp 的情况下运行的程序执行时间是 6.956 秒,当我尝试并行化 for 循环时我的执行时间大于 3 分钟(那是因为我自己结束了它)。关于并行化此代码,我做错了什么?

第二次尝试

    int ncip( int dim, double R)
{
int i;
int r = (int)floor( R);
if ( dim == 1)
{ return 1 + 2*r;
}


#pragma omp parallel
{
int n = ncip( dim-1, R); // last coord 0
#pragma omp for reduction (+:n)
for( i=1; i<=r; ++i)
{
n += 2*ncip( dim-1, sqrt( R*R - i*i) ); // last coord +- i
}

}

return n;

}

最佳答案

你做错了!

(1) 变量n存在数据竞争。如果要并行化在同一内存区域中写入的代码,则必须使用reduction(在 for 中)、atomiccritical 避免数据危害。

(2) 可能您启用了嵌套并行性,因此每次您调用函数 ncip 时程序都会创建一个新的并行区域。应该是这个主要问题。对于递归函数,我建议您只创建一个 并行区域,然后使用pragma omp task

不要与 #pragma omp for 并行化并尝试使用 #pragma omp task。看这个例子:

int ncip(int dim, double R){
...
#pragma omp task
ncip(XX, XX);

#pragma omp taskwait
...
}

int main(int argc, char *argv[]) {
#pragma omp parallel
{
#pragma omp single
ncip(XX, XX);
}
return(0);
}

更新:

//Detailed version (without omp for and data races)
int ncip(int dim, double R){
int n, r = (int)floor(R);

if (dim == 1) return 1 + 2*r;

n = ncip(dim-1, R); // last coord 0

for(int i=1; i<=r; ++i){
#pragma omp task
{
int aux = 2*ncip(dim-1, sqrt(R*R - i*i) ); // last coord +- i

#pragma omp atomic
n += aux;
}
}
#pragma omp taskwait
return n;
}

PS:您不会因此获得加速,因为创建任务的开销比单个任务的工作量大。您可以做的最好的事情是将此算法重新编写为迭代版本,然后尝试对其进行并行化。

关于c++ - 使用 OpenMP 并行化 C++ 代码,并行计算实际上更慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37420289/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com