C ++多线程给出不同的结果[重复]

Posted

技术标签:

【中文标题】C ++多线程给出不同的结果[重复]【英文标题】:C++ MultiThreading giving different result [duplicate] 【发布时间】:2019-10-10 08:58:35 【问题描述】:

我对 C++ 中的多线程有点陌生,我只是尝试使用 OMP 完成一些简单的 for 循环。具体来说,对于这个函数,用户指定大小的数组n 用 0 到 99(含)之间的随机整数填充。然后使用正常的for 循环计算该数组的总和一次,然后再使用#pragma omp parallel for 循环计算一次。出于某种原因,随着n 变大,函数返回不同的结果。比如n = 10,输出如下:

REGULAR FOR LOOP SUM: 1216
REGULAR FOR LOOP RUNNING TIME: 0.000003

OMP FOR LOOP SUM: 1216
OMP FOR LOOP RUNNING TIME: 0.000205

n = 100 时,输出如下:

REGULAR FOR LOOP SUM: 4946
REGULAR FOR LOOP RUNNING TIME: 0.000003

OMP FOR LOOP SUM: 3999
OMP FOR LOOP RUNNING TIME: 0.000247

这是我的REGULAR FOR LOOP 代码:

int sum = 0;
  for(int i = 0; i < n; i++) 
    sum += A[i];
  
  return(sum);

这是我的 OMP FOR LOOP 代码:

int sum = 0;
  int i;
#pragma omp parallel shared(A, n) private(i) num_threads(4)
  
    #pragma omp for
    for(i = 0; i < n; i++) 
      sum += A[i];
    
  
  return(sum);

为什么OMP FOR LOOPn = 100 返回不同的总和?另外,为什么OMP FOR LOOP 的运行时间大于REGULAR FOR LOOP?多线程不是为了减少运行时间吗?

【问题讨论】:

第二部分,当使用 OMP 时,您必须生成新线程,这会增加开销。仅当开销小于仅执行循环的成本时,多线程才有优势。尝试数十亿的数字,您可能会有所作为。话虽如此,通过矢量化,在您的情况下,一个简单的循环可能已经是并行的(在某种程度上)。 另外,使用您的代码,我得到了相同的答案。两者的A数组是一样的吗? 当您省略任何必需的缩减子句时 如果这个问题被称为愚蠢,它可能被改写为为什么不使用归约子句。如果您对获得性能感兴趣,那么问题会变得更加复杂。即使在循环计数为 100 时,simd 优化也可能不会获得收益,并且 omp 并行可能会失去性能。仅针对 simd 优化,具体取决于您的编译器 omp simd reduction 可能不如自动矢量化工作。 @Zulan 公认的答案确实有效。看来减少条款是必要的。 【参考方案1】:

你有sum的竞争条件:

sum += A[i];

这里有多个线程从sum 读取并从中写入一个新值。如果另一个线程基于即将被另一个线程覆盖的值进行增量,您可能会在此处丢失一些增量。

这里需要互斥锁或使用原子增量。

【讨论】:

以上是关于C ++多线程给出不同的结果[重复]的主要内容,如果未能解决你的问题,请参考以下文章

多线程有时会给出不同的输出[重复]

[C++11 多线程异步] --- std::promise/std::future

[C++11 多线程异步] --- std::promise/std::future

Openmp 多线程代码在使用多个线程时给出不同的答案

Java - 多线程CallableExecutorsFuture

[C++11 多线程异步] --- std::promise/std::future