2017-06-07 17 views
0

ここでは、「種類」の動的なフラットコンテナを持つスレッドプールがあるとします。このプールは、パフォーマンスを向上させるためにメモリがスタック上にあるため、最大容量がxです。最小限のコードで良いスレッドプールのキューサイズ

(私は特定に取得する必要はありません):

template <int32 QSIZE, int32 PSIZE> class ThreadPool 
{ 
public: 
ThreadPool() 
{ 
    for (int32 i = 0; PSIZE > i; ++i) 
    { 
     m_Workers.push(Thread(thread_main, m_Queue, m_Signal, m_IsRunning)); 
    } 
} 

~ThreadPool() 
{ 
    //Wait and destroy all threads 
} 

void run(Task task) 
{ 
    m_Queue.push(task); 
    m_Signal.wake_all(); 
} 

private: 
    FlatVector<Thread, PSIZE> m_Workers; //PSIZE --> max capacity 
    FlatQueue<Task, QSIZE> m_Queue; //QSIZE --> max capacity 
    ConditionVariable   m_Signal; 
    AtomicBool    m_IsRunning; 
}; 

class Taskは、バインドされたパラメータと意味動かすとインプレース関数の実装です。

FlatVectorは、メモリがスタック上にあり、最大容量がPSIZE(プールサイズ)のベクタです。

FlatQueueは、基本的にQSIZE(キューサイズ)の容量を持つキューと同じ構築物である

一つTaskは、512ビットの最大サイズを有します。

最悪の場合、スレッドプールのタスクキューがどのくらい大きくなるべきでしょうか? (可能であれば、与えられた例を考慮して、可能ならば通常のスレッドプールの推測も問題ありません)

ほとんどの場合、私のプールは8つのスレッドで実行されています。プールを使用すると、スレッド数が増えるというメリットがあります。

タスクをタスクバンドルにパッケージ化する方が良いでしょうか(この例では512ビットを超えない限り)、計算をスキップするだけでいいですか?このフレームにもう配置できず、次のフレームでそれらを計算することはできませんか?物理計算は2フレーム分計算されます。

私はキューサイズを64から128の間で選択していますが、パフォーマンスはそれほど優れていませんが、実際にはプール内の128のタスクが同時に感じられます。この量のメモリを無駄にしたくありません。

時々私は私が高負荷でプールを設定した場合、同時にプール内の64個のタスクの制限を超えています。 (私は最初の場所でのプールのサイズを大きくすることを決めた理由です。)

私のプールに、単一の512ビットのタスク(最悪の場合)を追加すると1,02と1,3電子パワー(-7)秒の間に何かを取ります私のシステムで

「通常の」スレッドプールとヒープ割り当てと移動セマンティクスを持つ「通常の」関数バインディングでは、1.8〜2.3 eのパワー(-5)秒の間に何かが起こります。この場合スタックされます。

+1

独自のスレッドプールクラスを作成することは、独自の文字列クラスを作成するのとよく似ています。おそらくあなたの人生で少なくとも一度はこれを行うことが大切ですが、他のプログラマと何をしたのかを比較することと同じくらい重要です。 *その*だけが洞察を提供します。そうすることで、その最適値はコードが実行されている特定のマシンに依存するランタイムの詳細なので、PSIZEがなくなります。そして、あなたは値を前もって推測し、その限界を超えて対処するためのまともな方法がないので、QSIZEも排除する可能性が非常に高いでしょう。それは重要です。 –

+0

公平なポイント、私はプール(通常)はCPUコアのサイズを持つべきであることを知っています。後で少なくともスレッド数は実行時にgetCoreCount()関数で置き換えられます(これはあなたが正しいところです)。それにもかかわらず、スタックコンテナの性能上の利点は強いため、QSIZEを持つスタックコンテナはそのままになります。実際には、私はあまり好きではない方法でオーバーフローを処理しています。キューがいっぱいであれば、メインスレッドで実行します。それは私が将来避けたいものです。そのために、より並列的に実行されるより良いソリューションを探しています。 – Mango

答えて

0

質問への一般的な答え:他のリソースに待つことなく、常に実行し、ワークロードのために

、論理的に、スレッドの最大数は、物理的なプロセッサの数と同じでなければなりません(か二度あればそのプロセッサにはハイパースレッディングがあります)。

他のリソース(ソケットの接続を待っているなど)を待つ作業負荷の場合、待機時間に応じて論理プロセッサより多くのスレッドを持つことで最大のスループットを得ることができます。多くのスレッドがブロックされていれば、何百ものスレッドが正常に動作します。タスクのレイテンシ境界部分とCPU集中部分を分離して、それぞれが異なるスレッド数を持つワークロードを完全に負荷分散することを検討できます。

スループットを最大化することを想定して、最適なスレッド数を経験的に決定できます。

制御理論を使用することで、スレッド数をソフトウェアで調整する興味深い解決策が得られます。 Philipp K. Janertによる「コンピュータシステムのフィードバック制御」はこれに関する良い参考資料です。

0

最悪の場合、スレッドプールのタスクキューがどのくらい大きくなるべきか、

私が求める権利の質問があると思います:どのくらい仕事が評価される前に待つことができ

  • 特定のタイプの新しいタスクが既存のタスクに優先しますか?
関連する問題