C++ STL并行累加函数错误?

C++ STL并行累加函数错误?,c++,multithreading,C++,Multithreading,有人知道为什么下面的脚本在多个线程上运行时会给出错误的结果吗?在累加中使用的向量长度有限制吗?当向量的长度大于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@c

有人知道为什么下面的脚本在多个线程上运行时会给出错误的结果吗?在累加中使用的向量长度有限制吗?当向量的长度大于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, %e\n",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;
}
ksaha@cswarmfe:g++-fopenmp test2.cc
ksaha@cswarmfe:导出OMP_NUM_线程=1
ksaha@cswarmfe:/出去
结果4000
时间0.000114875
ksaha@cswarmfe:导出OMP_NUM_线程=2
ksaha@cswarmfe:/出去
0.000000e+00,1.998000e+03
3.996000e+03、1.998000e+03
结果7992
时间0.000231437
ksaha@cswarmfe:导出OMP_NUM_线程=4
ksaha@cswarmfe:/出去
0.000000e+00,9.980000 E+02
1.996000e+03、9.98000E+02
3.992000e+03,9.98000E+02
5.988000e+03、9.98000E+02
结果7984
时间0.000265011
//============================================================
#包括
#包括
#包括
#包括
命名空间PAR=STD::
双y函数(双x,双y){
如果(y!=2)printf(“%e,%e\n”,x,y);
返回x+2.0*y;
}
int main(int argc,字符**argv)
{
双t=omp_get_wtime();
int err=0;
标准:向量向量向量(1000,2.0);

对于(int i=0;i要获得一致的结果,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

要获得一致的结果,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

要获得一致的结果,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

要获得一致的结果,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)不关联,因此结果取决于操作顺序。

二进制操作(x+2*y)不关联,因此结果取决于操作顺序。

二进制操作(x+2*y)不关联,因此结果取决于操作顺序。

二进制操作(x+2*y)不是关联的,因此结果取决于操作顺序。

欢迎使用堆栈溢出。我建议您在帖子中添加更多标记,尤其是您使用的语言。这将吸引更多能够回答您问题的观众。请定义“错误答案”。浮点数算法不是可交换的,因此预计不会并行累加不会给出与串行累加完全相同的结果。但是,在大多数情况下,它们应该在较小的公差范围内相同。实际上,这里的情况是(累加所有相同大小的正数)在并行执行时更准确。也就是说,对于一个合理的加法函数来说。这一个不是。欢迎使用堆栈溢出。我建议您在帖子中添加更多的标记,尤其是您使用的语言。这将吸引更多的观众,他们可能能够回答您的问题。定义“错误答案”。浮点算术不是com变异的,因此预计并行累加不会给出与串行累加完全相同的结果。但是,在大多数情况下,它们应该在较小的公差范围内相同。实际上,这里的情况是(累加相同大小的正数)在并行执行时更准确。也就是说,对于一个合理的加法函数来说。这一个不是。欢迎使用堆栈溢出。我建议您在帖子中添加更多的标记,尤其是您使用的语言。这将吸引更多的观众,他们可能能够回答您的问题。定义“错误答案”。浮点算术不是com因此,预计并行累加不会给出与串行累加完全相同的结果。但是,在大多数情况下,它们应该在较小的公差范围内相同。实际上,这里的情况(累加为正