0

クアッドコアで4つの作業スレッドと1つのI/Oスレッドを実行している場合、スレッドの1つが別のスレッドとオーバーラップします。sched_yield()して現在のタイムスライスを他のスレッドに譲ることができるように、常に別のスレッドとオーバーラップしているのが入力スレッドであることを確認するにはどうすればよいですか。オーバーラップしているのが2つのワーカースレッドの場合、入力スレッドのyieldは効果がありませんよね?sched_yieldはとにかく別のコアから別のスレッドをもたらしますか?

#include <sched.h>
#include <pthread.h>
void test(void*) {
   while(1) {}
}
int main (void) {
   pthread_t t; 
   for(int i = 0;i < 4;i++)
       pthread_create(&t,0,(void*(*)(void*))test,0); //workers
   while (1) {
       sched_yield(); //input thread
   }
   return 0;
}

編集 入力スレッドは、着信メッセージをポーリングする必要があります。私が使用しているライブラリ(MPI)は割り込み駆動型ではなく、条件変数はこのコンテキストでは役に立ちません。入力スレッドでやりたいことは、条件を一度チェックして、そのタイムスライスをあきらめることです。すべてのスレッドを実行するのに十分なコアがある場合、入力スレッドはそれ自体のコアで実行されます。そうでない場合は、最小数のチェック、つまりタイムスライスごとに1回実行されます。私は十分に明確であることを願っています。

4

2 に答える 2

1

あなたが探しているグーグル可能なフレーズは「CPUアフィニティ」です。

たとえば、このSOの質問を参照してください。

各ワーカースレッドが異なるコアで実行されていることを確認すると、指定された目標が達成されます。

多くのコメント投稿者がアプリケーションの設計について正当な懸念を投稿していると思います。頭の中にある設計が実際に達成したい最終目標を効果的に達成することを確認するために、これらの会話を拡張することを検討することをお勧めします。

于 2013-03-09T03:45:26.180 に答える
1

うーん、MPI_recvは、それを変更するために特別なことをしない限り、ブロックしていると主張します。MPIの基盤となる通信インフラストラクチャは複雑であり、「ブロッキング」がselect()の呼び出しでネットワークソケットを待機するまで拡張されるかどうかはわかりません。あなたはそうではないと言っているようなものですが、MPIの複雑さを考えると、私はそれを信じることができます。

MPIの内部

したがって、ブロッキングモードのMPI_recvに必然的にポーリングが含まれる場合は、下のライブラリが実行していることを正確に把握する必要があります。うまくいけば、それは賢明な世論調査です(つまり、nanosleep()の呼び出しを伴う世論調査)。そのためのOpenMPIソースコード(eek)を見るか、これとGTKWaveを使用して、そのスケジューリング動作がどのようになっているのかをグラフィカルな方法で確認できます(Linuxを使用していると想定しています)。

ポーリングループでスリープしている場合は、Linuxカーネルのバージョンが重要です。最近のカーネル(おそらくPREEMPT_RTパッチセットが必要です-覚えていないのではないかと思います)は、短時間でも適切なタイマー駆動のスケジュール解除されたスリープを実行するため、CPU時間を使用しません。古い実装では、短いスリープのためにビジーループに入るだけで、これはあなたにとって良くありません。

それがまったく眠っていない場合、それはより困難になるでしょう。非ブロッキングモードでMPIを使用し、ポーリング/スリープを自分で行う必要があります。

スレッドの優先順位

スリープを使用してまたはMPIのコードポーリングを取得したら、スレッドの優先順位とOSスケジューラを使用して問題を解決できます。一般に、I/Oスレッドをワーカースレッドよりも優先することをお勧めしますこれにより、I / Oのもう一方の端のプロセスが、I/Oスレッドをプリエンプトする作業スレッドによってブロックされるのを防ぎます。このため、スケジューラーはスレッドをスリープ状態にしないため、sched_yield()はお勧めできません。

スレッドアフィニティ

一般的に、少なくともまだ、私はそれを気にしません。5つのスレッドと4つのコアがあります。それらのスレッドの1つは常にがっかりします。(上記のように)ポーリングを制御できれば、カーネルにできる限りのことを整理させることができれば、問題はないはずです。

- 編集 -

私は行って、MPIとスレッドをもう一度見て、なぜそれが気に入らなかったのかを再発見しました。MPIはプロセスを相互通信し、各プロセスには「ランク」があります。MPIはスレッドセーフですが、スレッド自体には独自のランクはありません。したがって、MPIはスレッド間で相互通信することはできません。これは、最近のマルチコアデバイスのMPIの弱点です。

ただし、4つの個別のプロセスがあり、I/Oスレッドがない場合があります。これは、コピー、移動、および保存されるデータの量の点で最適ではない可能性があります(ネットワークトラフィックの4倍、使用されるメモリの4倍など)。ただし、計算時間:I / O時間の比率が十分に大きい場合は、単純なソースコードのためにその非効率性に耐えられる可能性があります。

于 2013-03-09T08:38:37.243 に答える