gpt4 book ai didi

c++ - 带有 std::vector 和带有缩减的标量变量的 OpenMP for 循环

转载 作者:行者123 更新时间:2023-11-30 02:30:35 36 4
gpt4 key购买 nike

我有这个代码:

#pragma omp declare reduction(* : scalar : omp_out *= omp_in)     
scalar like=1;
vector<scalar>& bigsum;
#pragma omp parallel for // reduction(* : like)
for (int m = 0; m < M-1; m++)
like *= bigsum[m];

我试图获得一致的结果,但它没有(竞争条件问题),但我应该如何解决它?因为它在代码中可见,所以我有自己的 reduction function 但它也不起作用。我应该注意标量和 std::vector 的任何技巧吗?

这里的标量变量只是通过在我创建的每个 double 上应用 log() 来覆盖 float ,因为有太多的 double 乘法和 double 乘法,并且其中几个的结果变得接近于零。例如,通过执行 log(),乘法变为加法等等。

一致答案的一个答案是:

    #pragma omp parallel
{
scalar loc = 1;
#pragma omp for
for (std::size_t m = 1; m < M;m++)
{
_flm[m-1] = Qratio[m-1] * k1 + k2;
bigsum[m-1] = kappa0omegaproduct + kappa[1] * _flm[m-1];
#pragma omp critical (reduce_product)
{
like *= bigsum[m-1];
}
}
}

这个答案是正确的,但是太慢了,在我的 8 核机器上几乎慢了 8 倍!

最佳答案

三天后我自己有了答案,并对我的发现做了解释。

我创建了自己的归约函数,如下所示:

#pragma omp declare reduction(* : scalar : omp_out *= omp_in) initializer (omp_priv (1))

诀窍是 omp_priv,显然减少值初始化很重要,这是我在 here 中学到的东西.

我通过像这样为循环应用 openmp 使代码更简单:

#pragma omp parallel for reduction (* : like)

非常简单干净。以这种新方式,代码得到并行化并且运行速度比我在问题正文中的代码运行得更快。不幸的是,它仍然比串行版本慢。也许是因为 std::vector 的使用,或者重载的算术运算很慢!?我不知道。代码太大,我无法以易于理解的方式将其复制粘贴到此处,并且不会让其他人阅读时感到头疼。

关于c++ - 带有 std::vector 和带有缩减的标量变量的 OpenMP for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38422224/

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