이것은 이상한 리눅스 버릇이 될 수도 있지만 매우 이상한 행동을하고 있습니다.비동기의 수수께끼 같은 행동
다음 코드는 동기화 된 버전의 합계를 비동기 버전과 비교해야합니다. 하나의 스레드 (하나의 코어 만 사용됨)로 프로그램을 관찰하면서 성능 향상 (캐싱이 아니라 코드를 두 개의 개별 프로그램으로 분할하는 경우에도 발생합니다)이 표시됩니다.
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
@nneonneo 예, 가상은 50GB와 같습니다 .-D –
64 비트 운영 체제에서는 가상 메모리가 부족하지 않습니다. 따라서 사용 빈도를 줄이거 나 사용량을 추적하는 데 아무런 요점이 없습니다. (적어도, 당신이 결핵에 빠지기 전까지는.) –