C++ std::thread 简单测试

注:本文仅个人测试记录,不具备通用性,如有错误,欢迎指正。谢谢!

环境:Win7 x64,32G内存,8核,2.7GHz

开发环境:VS2015, Release

目标:C++ 多线程在内存、线程数量、耗时方面简单测试

代码

#include <iostream>
#include <sstream>
#include <vector>
#include <array>
#include <thread>
#include <time.h>
#include <memory>
using namespace std;

const int numberCount = 1e10;

void Test()
{
    std::vector<int> data(numberCount);
    for (int i = 0; i < numberCount; ++i)
    {
        data[i] = 1;
    }
}

void DoubleTest()
{
    Test();
    Test();
}

int main()
{
    int count = 8;
    int startTime = clock();
    for (int i = 0; i < count; ++i)
    {
        Test();
    }
   
    int endTime = clock();
    cout << "single time : " << (endTime - startTime) << endl;

    std::thread threads[8];
    for (int i = 0; i < count; ++i)
    {
        threads[i] = thread(Test);
    }

    for (int i = 0; i < count; ++i)
    {
        threads[i].join();
    }
    int endTime2 = clock();
    cout << "mul time : " << (endTime2 - endTime) << endl;

    system("pause");
}

测试结果

插入一句:如果Test()函数中仅仅是int赋值,没有vector,测试结果单线程永远比多线程快,时间为多线程的1/2左右,原因不明!


使用单线程运行时:

内存: 13% ,25%, 20%,30%,24%...在一定范围内上下浮动

耗时: 16727 ms


使用多线程运行时,join()的位置不同结果也不同,如下图所示:

A: 如果分开separate:

内存: 18%,32%,49%,62%,90%,98%,然后停了1,2分钟,99%,电脑卡死,重启电脑

测试了两次,都是卡死,必须重启电脑,所以这种方式存在危险。

耗时: 卡死,XXXms

然后把代码改成4个线程,每个线程计算两个函数,就可以计算成功

内存: 17%,30%,44%,58%,72%,84%,80%,45%,22%,37%,49%,63%,78%,84%,64%,25%,17%结束

耗时: 第一次 14872 ms ,第二次 15327ms.....

B: 如果不分开 merge:

内存:变化上大致等于单线程

耗时:16488ms,略等于单线程

测试了多次,merge方式和单线程方式内存耗时几乎相等,可以认定两者相等。


首先确认一点,join必须分开,而且网上很多示例都是splite的,所以以splite方式作为目标继续深入。

上面是循环了8次进行的测试,然后for循环4次,测试3遍,结果如下:

测试三次,发现splite的时间要比单线程时间少一点。

然后for循环2次进行测试,测试3遍,结果如下:

测试结果:多线程仅比单线程耗时少1s左右,时间上并没有成倍关系,而且使用多线程还会存在系统崩溃的危险!


到现在需要思考以下问题

1. 线程数量如何确定,每个线程所处理的数据量大小如何确定

2. 如何提升计算效率,时间上的成倍关系如何体现


分析

第一个问题,线程数量如何确定?

百度搜到的结果是使用 std::thread::hardware_concurrency(),

通过这个函数得到了 8,然后查看计算机CPU核数也的确是8,但编程的结果很明显 8个线程是不对的!

个人推测:以32G为例,如果是8核,平均每个线程处理的数据量理想状态是4G,加上硬件本身计算是用1000而不是1024,

还要考虑系统其它进程占用资源,所以实际可用内存肯定不够4G,假设为3.5G

粗略换算:3.5G = 3 500M=3 500 000KB=3 500 000 000B

而我们的vector<int>data(1e10) 所占用的内存=sizeof(int) *data.size() = 4* 1e10= 40 000 000 000B

其实这里存在一个误区,就是int值的范围,如果给int变量赋值1e10, 它实际的值是1 410 065 408

重新计算vector<int>data(1e10) 所占用的内存=sizeof(int) *data.size() = 4* 1410065408= 5 640 261 632B

也就是说当我们开了8个线程时,需要的内存大于分配的内存,所以就会造成卡死的情况。

所以我们在设置线程数量时,首先要评估计算量所需内存。

个人建议:如果你的内存是32G,那么你的程序分配的内存应该在16G上,因为32G全部分配是不可能的,

而且越到后面的线程,调试结果看起来越慢。确定好分配的内存空间后,然后根据计算量X,线程数=16/X

第二个问题,效率提升并没有成倍的缩减啊,这是为什么呢?

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值