gpt4 book ai didi

c++ - For循环性能和多线程性能问题

转载 作者:太空狗 更新时间:2023-10-29 20:12:18 24 4
gpt4 key购买 nike

我有点无聊所以我想尝试使用 std::thread 并最终测量单线程和多线程控制台应用程序的性能。这是一个两部分的问题。因此,我从大量整数 vector (800000 个整数)的单线程求和开始。

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;

然后我添加了基于范围和基于迭代器的 for 循环,并使用 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 循环之间的 Debug模式应该有这么大的区别吗?甚至在 Release模式下有 1 毫秒的差异?

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

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 结束。缓存乒乓?还有别的吗?如果我做错了什么,正确的方法是什么?此外,如果它是相关的,我在具有 8 个线程的 i7 上进行了尝试,所以是的,我知道我没有计算主线程,但是使用 7 个单独的线程进行了尝试并且几乎得到了相同的结果。

编辑:抱歉忘记提到这是在 Windows 7 上使用 Visual Studio 2013 和 Visual Studio 的 v120 编译器或任何它所谓的。

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

最佳答案

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

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

关于c++ - For循环性能和多线程性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28588267/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com