C++ OpenMP:缩减和共享

C++ OpenMP:缩减和共享,c++,openmp,C++,Openmp,我有以下代码,这将导致错误的输出 #pragma omp parallel private(i,piold) shared(pi,sign) { #pragma omp for reduction(+:pi) schedule (static) for (i = 0; i < 100000; i++){ piold = pi; pi += sign/(2*i+1); sign=-sign; } } pi = 4*pi; #pra

我有以下代码,这将导致错误的输出

#pragma omp parallel private(i,piold) shared(pi,sign)
{
#pragma omp for reduction(+:pi) schedule (static)
  for (i = 0; i < 100000; i++){
        piold = pi;
        pi += sign/(2*i+1);
        sign=-sign;
  }
}
  pi = 4*pi;
#pragma omp并行私有(i,piold)共享(pi,sign)
{
#用于缩减(+:pi)计划的pragma omp(静态)
对于(i=0;i<100000;i++){
piold=pi;
pi+=符号/(2*i+1);
符号=-符号;
}
}
pi=4*pi;
我有点迷路,因为我是OpenMP新手。让我困惑的是如何在线程之间传递
符号
pi
piold
?它们不能共享,因为备用迭代需要不同的值。一种方法是将迭代划分为奇数和偶数,但这似乎效率很低

在这种情况下有什么建议吗?

看起来像是你试图用它来近似pi

  • C++支持在范围中声明迭代,因此将i从私有中删除

    for(无符号整数i=0;i<10000;i++)

  • 可以根据i的奇偶属性来识别符号,因此请改用(i&1)检查,并将符号从private中删除

        int sign = 1 - (i & 1);
        pi += (sign == 1 ? 1f : -1f) / (2 * i + 1);
    
  • piold不影响最终结果pi,从私有

  •     int sign = 1 - (i & 1);
        pi += (sign == 1 ? 1f : -1f) / (2 * i + 1);
    
你可以阅读更多。因为我现在没有支持OpenMP的编译器,所以我无法测试并提供示例代码。但我建议两种情况:

  • 使用openmp节通过i的奇数/偶数将公式的(+)和(-)分为两个线程。你将有两个部分
双加号=0.0

for (int i = 0; i < 5000; i++)
        plus += (4 * i + 1);
  • 对pi使用reduce子句

谢谢您的回复。我做了一些代码修改(共享列表),随着迭代次数的增加,我得到了更好的结果。我试图理解如何在for循环中对sign进行if条件检查。假设
sign
I
都是整数变量,
sign
最初是
1
-1
sign/(2*I+1)
将给出除第一次迭代之外的所有
0
。另外,虽然我不了解OMP,但将
sign
同时声明为private和shared对我来说似乎是矛盾的。sign private和shared是一个错误。我已经在这里更正了我的代码。你得到的结果是错误的吗?在
sign=-sign
符号
共享会导致线程之间的数据争用,因此结果是错误的。将
签名
设为私有,并在每次迭代中仅基于
i
的值进行计算,例如,如下面的答案所示。
pi = plus - minus;