加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 用于循环性能和多线程性能问题

发布时间:2020-12-16 09:56:31 所属栏目:百科 来源:网络整理
导读:我有点无聊所以我想尝试使用std :: thread并最终测量单线程和多线程控制台应用程序的性能.这是一个两部分问题.所以我开始使用一个大量的整数向量(800个整数)的单线程和. int sum = 0;auto start = chrono::high_resolution_clock::now();for (int i = 0; i 8
我有点无聊所以我想尝试使用std :: thread并最终测量单线程和多线程控制台应用程序的性能.这是一个两部分问题.所以我开始使用一个大量的整数向量(800个整数)的单线程和.

int sum = 0;
auto start = chrono::high_resolution_clock::now();

for (int i = 0; i < 800000; ++i)
    sum += ints[i];

auto end = chrono::high_resolution_clock::now();
auto diff = end - start;

然后我添加了基于范围和迭代器的循环,并使用chrono :: high_resolution_clock以相同的方式测量.

for (auto& val : ints)
    sum += val;

for (auto it = ints.begin(); it != ints.end(); ++it)
    sum += *it;

此时控制台输出看起来像:

index loop: 30.0017ms
range loop: 221.013ms
iterator loop: 442.025ms

这是一个调试版本,所以我改为发布,差异是?1ms支持基于索引.没什么大不了的,只是出于好奇:这三个for循环之间的调试模式有这么大差异吗?或者甚至在发布模式下1ms的差异?

我转向线程创建,并尝试使用此lambda对数组进行并行求和(通过引用捕获所有内容,以便我可以使用int的向量和先前声明的互斥量),使用基于索引的.

auto func = [&](int start,int total,int index)
{
    int partial_sum = 0;

    auto s = chrono::high_resolution_clock::now();
    for (int i = start; i < start + total; ++i)
        partial_sum += ints[i];
    auto e = chrono::high_resolution_clock::now();
    auto d = e - s;

    m.lock();
    cout << "thread " + to_string(index) + ": " << chrono::duration<double,milli>(d).count() << "ms" << endl;
    sum += partial_sum;
    m.unlock();
};

for (int i = 0; i < 8; ++i)
    threads.push_back(thread(func,i * 100000,100000,i));

基本上每个线程总计是总数组的1/8,最终的控制台输出是:

thread 0: 6.0004ms
thread 3: 6.0004ms
thread 2: 6.0004ms
thread 5: 7.0004ms
thread 4: 7.0004ms
thread 1: 7.0004ms
thread 6: 7.0004ms
thread 7: 7.0004ms
8 threads total: 53.0032ms

所以我想这个问题的第二部分是这里发生了什么? 2个线程的解决方案也以~30ms结束.缓存ping pong?别的什么?如果我做错了什么,那么正确的做法是什么?另外,如果它是相关的,我在8个线程的i7上尝试这个,所以是的我知道我没有计算主线程,但尝试了7个独立的线程,并且几乎得到了相同的结果.

编辑:抱歉忘了提到这是在Windows 7上使用Visual Studio 2013和Visual Studio的v120编译器或其他任何调用.

EDIT2:这是整个主要功能:
http://pastebin.com/HyZUYxSY

解决方法

在未打开优化的情况下,在幕后执行的所有方法调用都可能是真正的方法调用.内联函数可能没有内联但真的被调用.对于模板代码,您确实需要打开优化以避免所有代码都按字面意思进行.例如,你的迭代器代码可能会调用iter.end()800,000次,而operator!=用于比较800,调用operator ==等等等等.

对于多线程代码,处理器很复杂.操作系统很复杂.您的代码并非仅在计算机上.您的计算机可以更改其时钟速度,切换到turbo模式,切换到热保护模式.将时间四舍五入到毫秒并不是很有帮助.可能是一个线程到6.49毫秒而另一个线程也是6.51并且它的舍入方式不同.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读