【发布时间】:2012-10-14 20:29:37
【问题描述】:
这可能是一些奇怪的 Linux 怪癖,但我观察到非常奇怪的行为。
以下代码应将求和数字的同步版本与异步版本进行比较。问题是我看到了性能提升(它不是缓存,即使我将代码分成两个单独的程序也会发生),同时仍将程序视为单线程(仅使用一个内核)。
strace 确实显示了一些线程活动,但像 top 克隆这样的监视工具仍然只显示一个使用过的内核。
我观察到的第二个问题是,如果我增加生成率,内存使用量就会激增。线程的内存开销是多少?使用 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;
}
【问题讨论】:
-
10GB 虚拟还是真实?虚拟内存使用量很容易爆炸,但实际内存使用量不应该那么高。
-
@nneonneo 是的,虚拟就像 50GB :-D
-
在 64 位操作系统上,虚拟内存并不稀缺。因此,尝试减少使用或跟踪使用了多少是没有意义的。 (至少,直到你对结核病大发雷霆。)
标签: c++ linux multithreading asynchronous c++11