4

std::async何度も呼び出すプログラムがあります。実行されるタスクはかなり短いです (それぞれ数百ミリ秒など)。スレッドの作成にはかなりのオーバーヘッドがあると思いますが、どうにかしてこれを回避できるのではないかと考えています。ジョブを列挙するコードは、ジョブの処理よりもはるかに高速に実行されます。したがって、私はすでに一種のプーリングを行っています。こんなふうになります。「ジョブ スロット」の配列を作成します。

template <typename T>
struct job {
  std::future <void> fut;
  std::vector <T*> *result;
  bool inUse;
}

並列コードを開始する前に、ジョブ スロットの配列を初期化し、結果ベクトルを 1 回だけ作成します。次に、ジョブ列挙コードがジョブを列挙するたびに、使用されていないジョブ スロットを探します。空きスロットがある場合は、(std::async を使用して) 新しいジョブを開始し、future をそのスロットに移動します。ジョブが実行され、結果ベクトルが埋められます。空きスロットがない場合、コードはスロット内の先物のいずれかの準備ができているかどうかを確認します。その場合、結果ベクトルを処理してから、そのスロットを使用します。そうでない場合は、数ミリ秒待機します。このコードは非常にうまく動作し、使用可能なプロセッサの数に正確に対応します。への呼び出しごとにstd::async新しいスレッドを作成します。実際、プロセス ID がスクロールしているのがわかります。このオーバーヘッドを取り除き、最初にスレッドを一度だけ作成したいと思います。どうやって進める?

このスレッドプールの実装を見つけました https://code.google.com/p/cppthreadpool/downloads/list が、これが効率的になるにはタスクに1〜2秒かかる必要があると述べています。派手なスケジューリングや優先度などは必要ありません。スレッドの繰り返しの構築と破棄のオーバーヘッドを取り除きたいだけです。

4

1 に答える 1

0

std::async を使用してタスクを作成するテスト プログラムを実行したところ、多くのタスクが同じスレッドで実行されていることがわかりました!! 実際、2 つのスレッドが 25 の非同期タスクを実行したことがわかります。そのため、標準ライブラリはすでにいくつかのスレッド プーリングを行っているようです。

    std::vector<std::future<void>> futures;
    for (int i = 0; i < 25; ++i)
    {
        auto fut = std::async([]
        {          
            std::cout << std::this_thread::get_id() <<std::endl;
        });
        futures.push_back(std::move(fut));
    }
    std::for_each(futures.begin(), futures.end(), [](std::future<void> & fut)
    {
        fut.wait();
    });
于 2013-04-09T14:35:12.610 に答える