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 LOOP
为n = 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