私は、待ち時間(分)が非常に長く、リソース消費量が非常に少ない多数のタスク(>> 100K)を持っています。潜在的にそれらはすべて並行して実行される可能性があり、私はstd::async
を使用して各タスクの未来を生成することを検討していました。std :: asyncが非同期で作成して実行するスレッドの最大数はいくらですか?
私の質問はです。std :: asyncが非同期で作成して実行するスレッドの最大数はいくらですか? (Ubuntu 16-xxまたはCentOS 7.x-x86_64でg ++ 6.xを使用)
実際に実行している(待機している)タスクが十分にない場合は、レイテンシのコストは非常に高くなります。答えに到達するために
は、私は、システムの機能をチェックして開始しました:
[email protected]:~/programming/cxx/async$ ulimit -u
43735
[email protected]:~/programming/cxx/async$ cat /proc/sys/kernel/threads-max
87470
これらの数字から、私が実行して43Kのスレッドのために取得することができるように期待していた(ほとんどが待っています)並行して。それを確認するために、私は個別のスレッドIDの数を確認するには、以下のプログラムを書いて、空のタスクと100K std::async
を呼び出すために必要な時間:
#include <thread>
#include <future>
#include <iostream>
#include <vector>
#include <algorithm>
#include <chrono>
#include <string>
std::thread::id foo()
{
using namespace std::chrono_literals;
//std::this_thread::sleep_for(2s);
return std::this_thread::get_id();
}
int main(int argc, char **argv)
{
if (2 != argc) exit(1);
const size_t COUNT = std::stoi(argv[1]);
std::vector<decltype(std::async(foo))> futures;
futures.reserve(COUNT);
while (futures.capacity() != futures.size())
{
futures.push_back(std::async(foo));
}
std::vector<std::thread::id> ids;
ids.reserve(futures.size());
for (auto &f: futures)
{
ids.push_back(f.get());
}
std::sort(ids.begin(), ids.end());
const auto end = std::unique(ids.begin(), ids.end());
ids.erase(end, ids.end());
std:: cerr << "COUNT: " << COUNT << ": ids.size(): " << ids.size() << std::endl;
}
時間は大丈夫だったが、異なるスレッドIDの数ははるかにました(32748の代わり43735)予想より少ない:
[email protected]:~/programming/cxx/async$ /usr/bin/time -f "%E" ./testAsync 100000
COUNT: 100000: ids.size(): 32748
0:03.29
それから私はfoo
でのスリープ・ラインは2S睡眠時間を追加するために非コメント。得られたタイミングは10Kタスク程度まで2Sと一致するが、それを超えていくつかの点で、いくつかのタスクは、エンドアップ同一のスレッドIDと各追加のタスクの2Sによる経過時間増加を共有:
[email protected]:~/programming/cxx/async$ /usr/bin/time -f "%E" ./testAsync 10056
COUNT: 10056: ids.size(): 10056
0:02.24
[email protected]:~/programming/cxx/async$ /usr/bin/time -f "%E" ./testAsync 10057
COUNT: 10057: ids.size(): 10057
0:04.27
[email protected]:~/programming/cxx/async$ /usr/bin/time -f "%E" ./testAsync 10058
COUNT: 10058: ids.size(): 10057
0:06.28
[email protected]:~/programming/cxx/async$ ps -eT | wc -l
277
だから、私の問題は、このシステムでは、限界は10Kのオーダーであると考えています。私は別のシステムでチェックし、限界は4Kのオーダーでした。
私は理解することはできません。
- をこれらの値は、簡単な
- は、Linux上のシステムグラムで
これらのスレッドはそれぞれ、OSからいくつかのリソースを取得する必要があります。スレッドスタックの標準的なデフォルトサイズは8MBなので、そのために合計_thread-count * 8MBのDRAMが必要です。より多くのスレッドを起動するだけでなく、リソースも必要です。[こちら](http://stackoverflow.com/questions/25814365/when-to-use-stdasync-vs-stdthreads)も参照してください。 – Arash
ほとんど同じくらいばかげた数の処理コアがないばかげた数のタスクはそれほど有用ではありません。スレッドは、プロセッサにアクセスするために時間を費やすのに多くの時間を費やします。スレッドプールの使用を検討してください。 – user4581301
@arashリンクに感謝します。 DRAMの使用に関しては、デフォルトのスレッドスタックサイズが8MBであっても、これが仮想メモリであると予想され、実際に必要なDRAMの量はスレッドが実際に使用しているもの(ページサイズに切り上げたもの)になります。私が間違っている? –