1

私がスレッドプールを持っているとしましょう(例はhttp://threadpool.sourceforge.net/かもしれません); そして私はこのコードを持っています:

class Demigod{ 
public:
   Demigod();
   void AskObedienceFast();
   void AskObedienceSlow();
   void WorkHardGodDamn();
   ~Demigod();
private:
   ThreadPool m_PitySlaves;
   int m_Quota;
};
Demigod::Demigod() : m_PitySlaves(manyPlease) { 
}
void Demigod::WorkHardGodDamn(){ 
    //something irelevant just to annoy slaves
}
void Demigod::AskObedienceFast() { 
    for(int q=0; q<m_Quota; ++q){
       m_PitySlaves.schedule(boost::bind(&Demigod::WorkHardGodDamn, this)); 
    }
    m_PitySlaves.wait();
}
void Demigod::AskObedienceSlow() { 
    ThreadPool poorSouls;
    for(int q=0; q<m_Quota; ++q){
       poorSouls.schedule(boost::bind(&Demigod::WorkHardGodDamn, this)); 
    }
    poorSouls.wait();
}
void main(){ 
   Demigod someDude;
   for(size_t i=0; i<dontstop; ++i){ 
      someDude.AskObedienceFast();
   }
}

AskObedienceFastは、AskObedienceSlowと比較して高速で機能しますか?このようにして、いくつかのスレッド(スレーブ)を作成し、呼び出しのたびにスレッドプールを作成する時間を無駄にすることなく、いつでも作業の準備を整えることができます。私は自分でコードを検証できることを知っていますが、スレッドプール内のスレッドが待機プロセスを実行しているように、これが根本的にどこかでパフォーマンスを低下させないのであれば、私の質問はもっと広いですか?コストのかかるスレッドプールの初期化(およびスレッド)を回避することになります。

4

1 に答える 1

2

「待機プロセス」のようなものはありません。スレッドが (条件付きで) 待機している場合、スケジューラは単純にそれをスキップします。したがって、そのようなスレッドは何もせず、切り替えも切り替えもされません。あなたが非常に正しく指摘したように、スレッド化で最もコストのかかるタスクはスレッドをセットアップすることです (ただし、すべての主要な OS は、最近のコアの増加に対応するために、可能な限りスレッドを最小限に抑えるための措置を講じています)。その後に、スレッドの切り替えが続きます。コンテキスト。AskObedienceSlowだから、なぜ恐ろしいのかがわかります。一時的なものは、建設と破壊にできるだけ時間がかからない「安価な」構造にする必要があります。ThreadPool間違いなくそのようなものではありません。平AskObedienceFastコンテキスト切り替えのオーバーヘッドから保護することはできませんが、そのため、スレッド プールが大きいほど常に優れているとは限らず、実際のワークロードに応じて慎重にバランスを取ることが最適なパフォーマンス サイズになります。最高のパフォーマンスを発揮する高負荷で高スループットのアプリケーションの一部は、まさにこの理由から、シングル スレッドのメッセージ パッシング デザインです。そのようなアプリケーション (Erlang など) に使用されるプログラミング言語は、明示的にスレッドレスです。

于 2012-11-08T10:33:42.853 に答える