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的奇数/偶数将公式的(+)和(-)分为两个线程。你将有两个部分
for (int i = 0; i < 5000; i++)
plus += (4 * i + 1);
- 对pi使用reduce子句
sign
和I
都是整数变量,sign
最初是1
或-1
,sign/(2*I+1)
将给出除第一次迭代之外的所有0
。另外,虽然我不了解OMP,但将sign
同时声明为private和shared对我来说似乎是矛盾的。sign private和shared是一个错误。我已经在这里更正了我的代码。你得到的结果是错误的吗?在sign=-sign代码>和符号
共享会导致线程之间的数据争用,因此结果是错误的。将签名
设为私有,并在每次迭代中仅基于i
的值进行计算,例如,如下面的答案所示。
pi = plus - minus;