C ++中的多线程程序显示与串行程序相同的性能

时间:2016-02-20 15:58:13

标签: c++ multithreading performance time

我只想用C ++编写一个简单的程序,它创建两个线程,每个线程用整数的平方(0,1,4,9,...)填充向量。 这是我的代码:

#include <iostream>
#include <vector>
#include <functional>
#include <thread>
#include <time.h>

#define MULTI 1
#define SIZE 10000000

void fill(std::vector<unsigned long long int> &v, size_t n)
{
    for (size_t i = 0; i < n; ++i) {
        v.push_back(i * i);
    }
}

int main()
{
    std::vector<unsigned long long int> v1, v2;
    v1.reserve(SIZE);
    v2.reserve(SIZE);
    #if !MULTI
    clock_t t = clock();
    fill(v1, SIZE);
    fill(v2, SIZE);
    t = clock() - t;
    #else
    clock_t t = clock();
    std::thread first(fill, std::ref(v1), SIZE);
    fill(v2, SIZE);
    first.join();
    t = clock() - t;
    #endif
    std::cout << (float)t / CLOCKS_PER_SEC << std::endl;
    return 0;
}

但是当我运行我的程序时,我看到,串行版本和并行版本之间没有显着差异(或者有时并行版本显示更糟糕的结果)。 知道会发生什么吗?

3 个答案:

答案 0 :(得分:2)

当我在i7上使用MSVC2015执行代码时,我观察到:

  • 在调试模式下,多线程为14s,而单线程为26s。所以几乎快了两倍。结果如预期。
  • 在发布模式下,多线程为0.3,而单线程为0.2,因此它的速度较慢,正如您所报道的那样。

这表明您的问题与优化fill()与创建线程的开销相比太短的事实有关。

另请注意,即使在fill()中有工作要做(例如未经优化的版本),多线程也不会将时间乘以2。多线程将增加多核处理器上的每秒总吞吐量,但是单独采用的每个线程可能比平时稍微慢一些。

修改:其他信息

多线程性能取决于很多因素,例如处理器上的核心数,测试期间运行的其他进程使用的核心,以及 doug < / strong>在他的评论中,多线程任务的配置文件(即内存与计算)。

为了说明这一点,这里的非正式基准测试的结果表明,对于内存密集型而言,单个线程吞吐量的降低要比浮点密集型计算快得多,并且全局吞吐量增长得慢得多(如果有的话):

enter image description here

为每个线程使用以下函数:

// computation intensive
void mytask(unsigned long long loops)
{
    volatile double x; 
    for (unsigned long long i = 0; i < loops; i++) {
        x = sin(sqrt(i) / i*3.14159);
    }
}

//memory intensive
void mytask2(vector<unsigned long long>& v, unsigned long long loops)
{
    for (unsigned long long i = 0; i < loops; i++) {
        v.push_back(i*3+10);
    }
}

答案 1 :(得分:0)

fill函数运行得如此之快,以至于线程开销可能与执行一样长。

将填充替换为需要花费大量时间才能执行的内容。作为第一步,请使用create or replace view FARMERS_DATA AS SELECT DISTINCT F.FNAME , F.LNAME , F.REGION , P.NAME , SP.NAME as SUB_PRODUCT_NAME , number(2) as PRICE FROM FARMERS F, PRODUCT P, SUB_PRODUCT SP WHERE SP.PRODUCT_ID = P.PRODUCTID ORDER BY F.FNAME

答案 2 :(得分:0)

大多数建议是正确的:只有当线程cpu加载(在你的情况下是乘法i * i)比共享内存访问加载(在你的情况下是v.push_back)更重要时,线程化任务将改善执行时间)。 您可以尝试使用此代码。您将看到线程的收益。 您可以使用unix命令

>time ./a.out 

更轻松地为您的代码计时。

#include <iostream>
#include <vector>
#include <functional>
#include <thread>
#include <time.h>
#include <math.h>

#define MULTI 1
#define SIZE 10000000

void fill(std::vector<unsigned long long int> &v, size_t n)
{
    int sum = 0;
    for (size_t i = 0; i < n; ++i) {
        for (size_t j = 0; j < 100; ++j) {
            sum += sqrt(i*j);
        }
    }
    v.push_back(sum);
}

int main()
{
    std::vector<unsigned long long int> v1, v2;
    v1.reserve(SIZE);
    v2.reserve(SIZE);
    #if !MULTI
    fill(v1, SIZE);
    fill(v2, SIZE);
    #else
    std::thread first(fill, std::ref(v1), SIZE);
    std::thread second(fill, std::ref(v2), SIZE);

    first.join();
    second.join();
    #endif
    return 0;
}