有谁知道为什么下面的脚本给出错误的结果,而运行在超过1个线程?累加函数中使用的向量的长度是否有限制?当向量的长度大于999时给出错误的答案。
ksaha@cswarmfe:g++ -fopenmp test2.cc
ksaha@cswarmfe:export OMP_NUM_THREADS=1
ksaha@cswarmfe:./a.out
result 4000
Time 0.000114875
ksaha@cswarmfe:export OMP_NUM_THREADS=2
ksaha@cswarmfe:./a.out
0.000000e+00, 1.998000e+03
3.996000e+03, 1.998000e+03
result 7992
Time 0.000231437
ksaha@cswarmfe:export OMP_NUM_THREADS=4
ksaha@cswarmfe:./a.out
0.000000e+00, 9.980000e+02
1.996000e+03, 9.980000e+02
3.992000e+03, 9.980000e+02
5.988000e+03, 9.980000e+02
result 7984
Time 0.000265011
//============================================================
#include <vector>
#include <iostream>
#include <numeric>
#include <parallel/numeric>
namespace par = std::__parallel;
double myfunction (double x, double y) {
if(y!=2) printf("%e, %en",x,y);
return x+2.0*y;
}
int main(int argc, char **argv)
{
double t = omp_get_wtime();
int err = 0;
std::vector<double> vec(1000,2.0);
for (int i=0; i<1000; i++)
if(vec[i]!=2) std::cout << vec[i] << "+++" << std::endl;
double init = 0.0;
// parallel
double result = par::accumulate(vec.begin(),vec.end(),init,myfunction);
std::cout << "result " << result << std::endl;
std::cout << "Time " << omp_get_wtime()-t << std::endl;
return err;
}
为了获得一致的结果,您的myfunction需要是关联的。在串行模式下,它一次只处理一个元素,所以myfunction总是被调用,x是累积值,y是数组中的一个条目。因此,总数是所有累积值之和的2倍,即4000。
但是当并行调用时,x和y都可能是累积值,如果你的myfunction不是关联的,你会得到不同的结果,这取决于处理顺序。
例如,在你的向量中有4个元素,串行版本将得到总共16个元素,但并行版本可以按如下方式处理,得到24个元素:
0.0 2.0 0.0 2.0
/ /
4.0 2.0 4.0 2.0
/ /
8.0 8.0
/
24.0
您的二进制操作(x+2*y)不是关联的,因此结果取决于操作的顺序。