gpt4 book ai didi

c++ - 异步的令人费解的行为

转载 作者:太空狗 更新时间:2023-10-29 21:47:34 25 4
gpt4 key购买 nike

这可能是一些奇怪的 Linux 怪癖,但我观察到非常奇怪的行为。

以下代码应该比较同步版本的求和数字和异步版本。问题是我看到了性能提升(这不是缓存,即使我将代码分成两个单独的程序也会发生),同时仍然观察到该程序是单线程的(只使用一个内核)。

strace 确实显示了一些线程事件,但是像 top clones 这样的监控工具仍然只显示一个已使用的内核。

我观察到的第二个问题是,如果我增加生成比率,内存使用量就会激增。线程的内存开销是多少?使用 5000 个线程,我得到大约 10GB 的内存使用量。

#include <iostream>
#include <random>
#include <chrono>
#include <future>
using namespace std;


long long sum2(const vector<int>& v, size_t from, size_t to)
{
const size_t boundary = 5*1000*1000;

if (to-from <= boundary)
{
long long rsum = 0;
for (;from < to; from++)
{
rsum += v[from];
}
return rsum;
}
else
{
size_t mid = from + (to-from)/2;
auto s2 = async(launch::async,sum2,cref(v),mid,to);

long long rsum = sum2(v,from,mid);
rsum += s2.get();
return rsum;
}
}

long long sum2(const vector<int>& v)
{
return sum2(v,0,v.size());
}

long long sum(const vector<int>& v)
{
long long rsum = 0;
for (auto i : v)
{
rsum += i;
}

return rsum;
}

int main()
{
const size_t vsize = 100*1000*1000;

vector<int> x;
x.reserve(vsize);

mt19937 rng;
rng.seed(chrono::system_clock::to_time_t(chrono::system_clock::now()));

uniform_int_distribution<uint32_t> dist(0,10);

for (auto i = 0; i < vsize; i++)
{
x.push_back(dist(rng));
}

auto start = chrono::high_resolution_clock::now();
long long suma = sum(x);
auto end = chrono::high_resolution_clock::now();

cout << "Sum is " << suma << endl;
cout << "Duration " << chrono::duration_cast<chrono::nanoseconds>(end - start).count() << " nanoseconds." << endl;

start = chrono::high_resolution_clock::now();
suma = sum2(x);
end = chrono::high_resolution_clock::now();

cout << "Async sum is " << suma << endl;
cout << "Async duration " << chrono::duration_cast<chrono::nanoseconds>(end - start).count() << " nanoseconds." << endl;

return 0;
}

最佳答案

也许您观察到正在使用一个内核,因为同时工作的线程之间的重叠太短以至于无法察觉。在现代硬件上从连续内存区域求和 500 万个值应该非常快,所以当父级完成求和时,子级可能才刚刚开始,父级可能大部分或所有时间都在等待子级的结果。您是否尝试增加工作单位以查看重叠是否变得明显?

关于性能提升:即使由于工作单元太小,线程之间的重叠为 0,多线程版本仍然可以受益于额外的 L1 缓存内存。对于这样的测试,内存可能会成为瓶颈,顺序版本将仅使用一个 L1 缓存,而多线程版本将使用与核心一样多的缓存。

关于c++ - 异步的令人费解的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12886246/

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