6

私は、24コアの共有Linuxコンピューターで超並列科学計算ジョブを実行しています。ほとんどの場合、このコンピューターで他に何も実行されていないときに、私のジョブは24コアに拡張できます。ただし、私のものではないシングルスレッドジョブが1つでも実行されている場合、24スレッドジョブ(私は高いnice値に設定)は(Linux表記を使用して)最大1800%のCPUしか取得できないようです。その間、CPUサイクルの約500%(ここでもLinux表記を使用)はアイドル状態です。誰かがこの動作と、他の誰かが使用していない23個のコアすべてを取得するために私ができることを説明できますか?

ノート:

  1. 関連する場合は、わずかに異なるカーネルバージョンでこれを観察しましたが、頭のてっぺんからどれを覚えているかはわかりません。

  2. CPUアーキテクチャはx64です。私の24コアのジョブが32ビットであり、競合している他のジョブが64ビットであるという事実が関係している可能性はありますか?

編集:私が今気づいたことの1つは、最大30スレッドになると、問題がある程度軽減されるように見えることです。最大2100%のCPUを使用できます。

4

5 に答える 5

7

これは、スケジューラが以前に実行していたのと同じCPUで各タスクを実行し続けようとしていることが原因である可能性があります(これは、タスクがワーキングセットをそのCPUのキャッシュに持ってきた可能性があるためです-「キャッシュホット」です")。

試すことができるいくつかのアイデアは次のとおりです。

  • コアの2倍のスレッドを実行します。
  • コアよりも1つまたは2つ少ないスレッドを実行します。
  • の値を減らします/proc/sys/kernel/sched_migration_cost(おそらくゼロまで)。
  • downの値/proc/sys/kernel/sched_domain/.../imbalance_pctを100に近づけます。
于 2010-05-14T01:53:00.413 に答える
2

スレッドを同期する必要がありますか?その場合、次の問題が発生する可能性があります。

4CPUシステムと4スレッドのジョブがあると仮定します。単独で実行すると、スレッドは4つのコアすべてを使用するようにファンアウトし、合計使用量はほぼ完璧になります(これを400%と呼びます)。

シングルスレッドの干渉ジョブを1つ追加すると、スケジューラーは2つのスレッドを同じCPUに配置する可能性があります。これは、2つのスレッドが通常の半分のペースで実行されていることを意味し(劇的な簡略化)、スレッドを定期的に同期する必要がある場合、ジョブの進行は最も遅いスレッドによって制限される可能性があります。この場合は、通常の半分の速度。使用率はわずか200%(4x 50%を実行しているジョブから)+ 100%(干渉ジョブ)= 300%になります。

同様に、干渉ジョブが1つのプロセッサの時間の25%しか使用しないと仮定すると、同じCPU上にスレッドの1つと干渉源が表示される可能性があります。その場合、最も遅いスレッドは通常の3/4の速度で実行され、合計使用率は300%(4x 75%)+ 25%= 325%になります。これらの数字で遊んでみてください。あなたが見ているものに似たものを思いつくのは難しくありません。

それが問題である場合は、優先順位を試して、歓迎されないタスクに使用可能なCPUのごく一部のみを与えることができます(I / O遅延は要因ではないと想定しています)。または、ご存知のように、スレッドを増やして、各CPUがたとえば2つのスレッドから、システムタスクを可能にするためのいくつかのスレッドを差し引いたものになるようにします。このように、24コアシステムは、たとえば46スレッドで最適に動作する可能性があります(これにより、常に2コアの時間の半分がシステムタスクに使用できるようになります)。

于 2010-05-13T22:00:43.693 に答える
1

スレッドは相互に通信していますか?

sched_setaffinityまたはを使用して、すべてのスレッドを手動でCPUにバインドしてみてくださいpthread_setaffinity_np。多くの関連するスレッドを操作する場合、スケジューラーはかなり馬鹿げている可能性があります。

于 2010-05-16T04:28:32.337 に答える
0

mpstat(パッケージの一部sysstat)を使用して、他のCPUが完全に使用されている間にCPU全体がアイドル状態になっているかどうかを判断することは価値があるかもしれません。topやvmstatよりも使用率の詳細が表示されるはずですmpstat -P ALL。CPUごとに1行を確認するために実行します。

実験として、各スレッドが個々のCPUにバインドされるように、各スレッドにCPUアフィニティを設定してみてください。これにより、タスクがスケジュールされているCPUをカーネルスケジューラに決定させない場合のパフォーマンスを確認できます。これは永続的な解決策としては適切ではありませんが、それが大いに役立つ場合は、スケジューラーがどこで不足しているかを知ることができます。

于 2010-05-13T18:27:42.933 に答える
0

ボトルネックはアプリケーションまたはカーネルのスケジューリングアルゴリズムにあると思いますか?スケジューリングパラメータの調整を開始する前に、単純なマルチスレッドアプリケーションを実行して、アプリケーションと同じ動作を示すかどうかを確認することをお勧めします。

// COMPILE WITH: gcc threads.c -lpthread -o thread
#include <pthread.h>
#define NUM_CORES 24

void* loop_forever(void* argument) {
    int a;
    while(1) a++;
}

void main() {
    int i;
    pthread_t threads[NUM_CORES];

    for (i = 0; i < NUM_CORES; i++)
        pthread_create(&threads[i], 0, loop_forever, 0);

    for (i = 0; i < NUM_CORES; i++)
        pthread_join(threads[i], 0);
}
于 2010-05-15T02:30:11.167 に答える