线程(c++ 中的并行计算)是不是与优化级别(gcc)不兼容?

Posted

技术标签:

【中文标题】线程(c++ 中的并行计算)是不是与优化级别(gcc)不兼容?【英文标题】:Is thread (parallel computing in c++) incompatible with optimization levels (gcc)?线程(c++ 中的并行计算)是否与优化级别(gcc)不兼容? 【发布时间】:2015-08-12 20:56:08 【问题描述】:

我正在尝试学习如何使用多线程,然后我编写了一个代码(见下文)。正如预期的那样,并行函数需要2.6s,而非并行需要6.4s

然后我尝试使用 gcc 提供的优化 -O3 来修改编译。这样,非并行函数耗时0s并行函数耗时2s!表明 -O3 没有作用于并行函数。

为什么优化级别对线程不起作用?有什么根本问题吗?我是不是做错了什么?

按照代码:

#include <iostream>
#include <ctime>
#include <cmath>
#include <vector>
#include <thread>
using namespace std;

#define N 1E8
#define num_sum std::thread::hardware_concurrency()

void fS(void)
    double sum;
    int i;
    for(i=0;i<N;i++)
        sum += sin(i*0.1);
    
//  cout << endl << sum << endl;    
    return;


void fS_N(vector<double>& sum,int j)
    int i;

    int imin,imax,intervalo;
        intervalo = N/num_sum;
        imin = j*intervalo;
        imax = (j+1)*intervalo;

    for(i=imin;i<imax;i++)
        sum[j] += sin(i*0.1);
       
    return;


int main()
    clock_t t;

    cout << "# disponiveis de nos/cpu: " << num_sum << endl;

    //no parallel
    t = clock();
    fS();
    t = clock()-t;
    cout << "\n Time (no parallel):";
    cout << ((double)t)/CLOCKS_PER_SEC << endl;     

    //parallel
    t = clock();    
    vector<thread> allsum;
    vector<double> Svalue(num_sum,0.);
    int j;

    for(j = 0; j<num_sum; j++)
        allsum.push_back(thread (fS_N, ref(Svalue),j) );
    

    for(auto &t : allsum)
        t.join();
    

    double Soma=0.;
    for (j=0;j<num_sum;j++)
        Soma += Svalue[j];
    
//  cout << Soma << endl;
    t = clock()-t;
    cout << "\n Time (parallel):";
    cout << ((double)t)/CLOCKS_PER_SEC << endl;     

return 0;

【问题讨论】:

当任何东西都为 0 时,你应该开始怀疑。您的基准无效。 嗯,0 的意思是 10^-5。 (我可以修改程序以显式生成它,但这不是重点) fS() 函数中,您计算​​一个从未使用过的总和。优化器足够聪明,不会计算未使用的值。 rs,嗯,最后 0 正是重点。 【参考方案1】:

您的“无并行”函数fS() 将值计算到不会去任何地方的局部变量中,fs_N() 对其参数进行计算。因此,当启用优化时,编译器会消除 fS() 的所有代码,因为它不会影响任何内容。您需要将该结果存储在某处(可能会返回该函数并可能稍后将其打印出来):

double fS(void)
    double sum;
    int i;
    for(i=0;i<N;i++)
        sum += sin(i*0.1);
    
//  cout << endl << sum << endl;    
    return sum;

【讨论】:

以上是关于线程(c++ 中的并行计算)是不是与优化级别(gcc)不兼容?的主要内容,如果未能解决你的问题,请参考以下文章

提升串行运行的线程,而不是并行运行

c++多线程编程:实现标准库accumulate函数的并行计算版本

Android内存优化1 了解java GC 垃圾回收机制2 GC执行finalize的过程

halcon算子并行和串行计算

java8与java11有啥不同

详解c++11多线程