これは奇妙なLinuxの癖かもしれませんが、私は非常に奇妙な振る舞いを観察しています。
次のコードは、同期されたバージョンの合計数を非同期バージョンと比較する必要があります。プログラムをシングルスレッド(1つのコアのみが使用されている)として観察しながら、パフォーマンスの向上が見られます(キャッシュではなく、コードを2つの別々のプログラムに分割した場合でも発生します)。
strace
いくつかのスレッドアクティビティを表示しますが、top
クローンなどの監視ツールは、使用されているコアを1つだけ表示します。
私が観察している2番目の問題は、スポーン率を上げると、メモリ使用量が爆発することです。スレッドのメモリオーバーヘッドはどれくらいですか?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;
}