为什么两个/四个线程比在C ++ 11多线程coing中执行vector inner_product的单个线程更慢?

时间:2015-09-03 05:39:18

标签: c++ multithreading c++11

参考c ++ 11多线程example,我尝试使用多线程来计算矢量dot_product结果。这里的基本思想是我们将向量分成两个或四个部分,并且并发计算每个部分的partial_sum。并在同步两个线程后进行求和。在这里,我只使用CPU和RAM资源。此外,我尝试创建一个大向量,以涵盖线程计划ovehead。

问题在于,两个/四个线程甚至比单个线程慢。但是使用两个线程时CPU利用率要高得多。因此,我相信该程序使用了两个物理内核。

平台和运行时间结果如下。有人说跑步时间要高一点。我不确定效率是否与操作系统有关。我还没有在Linux上测试代码,有人帮我做测试吗?

非常感谢任何帮助。

这是我的线程实现:

#include<iostream>
#include<thread>
#include<vector>
#include<mutex>
#include<ctime>
#include<numeric>
#include<iterator>

using namespace std;
vector<int> boundary(int num, int parts)
{
    vector<int >bounds;
    int delta = num / parts;
    int remainder = num % parts;
    int prev = 0, next = 0;
    bounds.push_back(prev);

    for(int i = 0; i < parts; i++)
    {
        next = prev + delta;
        if(i == parts - 1)
            next = next + remainder;
        bounds.push_back(next);
        prev = next;
    } 

    return bounds;
}

void dot_product(const vector<int>& v1, const vector<int>& v2, int& result, int L, int R, int tid)
{
    int partial_sum = 0;

    for(int i = L; i < R; i++)
        partial_sum += v1[i] * v2[i];

    //lock_guard<mutex> lock(barrier);
    //cout << "tid: " << tid<< endl;
    result = partial_sum;
}

int main(int argc, char* argv[])
{
    clock_t start, end;
    int numOfElement = 500000000;
    // Change the thread number here
    int numOfThread = 2;
    int result[numOfThread] = {0};
    vector<thread> threads;

    // Fill two vectors with some values 
    vector<int> v1(numOfElement, 1), v2(numOfElement, 2);

    // Split numOfElement into nr_threads parts
    vector<int> limits = boundary(numOfElement, numOfThread);

    start = clock();
    // Launch multi_threads:
    for(int i = 0; i < numOfThread; i++)
        threads.push_back(thread(dot_product, ref(v1), ref(v2), ref(result[i]), limits[i], limits[i+1], i)); 

    // Join the threads with the main thread    
    for(auto &t:threads)
        t.join();

    int sum = accumulate(result, result+numOfThread, 0);
    end = clock();  
    //cout << limits[0] <<" " << limits[1]<<" "<<limits[2]<<endl;
    cout << "results: " << sum << " time elapsed: "<< double(end - start) / CLOCKS_PER_SEC << endl;
    return 0;
}

平台:

操作系统:Win8 64位

CPU:I3-3220(2C4T)

RAM:12G

IDE:Dev-C ++ 5.11,TDM-GCC 4.9.2发布

到目前为止的结果:

1线程:14.42秒,CPU:60%,RAM:3.82G(仅限程序,修改后)

2个主题:19.65秒,CPU:82%,RAM:3.82G(仅限程序,修改后)

4个主题:22.33秒,CPU:99%,RAM:3.82G(仅限程序,修改后)

更新 参考这个link,我为GCC设置-O2优化,但代价是link报告的编译时间。现在结果似乎正常如期望,这与@yzt报道的相似。此外,我用 chrono 替换 clock 以进行高分辨率调整。

新结果:

1个主题:0.57秒

2个主题:0.31秒

4个主题:0.28秒

似乎2线程几乎接近我的CPU中的最佳速度,我想这背后的原因是I3只能获得2个物理内核和4个逻辑内核。

0 个答案:

没有答案