マルチスレッドアプリケーションを使用したマルチコアシステムの負荷平均の理解

マルチスレッドアプリケーションを使用したマルチコアシステムの負荷平均の理解

私たちのシステムの負荷平均に奇妙な状況があります。一日中アイドル状態のZAGというアプリケーションを実行しています。しかし、80分ごとに5〜15分間持続する一種の爆発的な活動があります。バースト時の負荷平均は60、70、80、100以上に上がります。興味深い事実:これらの高いバースト中に、htopのCPU使用率はCPUあたり10〜20%しか表示されないことがわかります。また、私が書いたスクリプトは、アイドル時間中にCPU使用率が低いことを示しています。

ps -eTo psr,user,pid,tid,cputime,class,rtprio,ni,pri,pcpu,stat,wchan:14,args | grep  ZAG | awk '{sum += $10} END{print sum;}'

535.0を返すことができます。つまり、ZAGアプリケーションのすべてのCPUパーセントを追加すると、CPUの535.0%、つまりシステムのすべてのCPU使用率が5.35 / 32または16.7%になります。簡単に言えば、CPUのどれも100%近く実行されていませんでした。

この場合、結果は約538.0%...少し高いだけです。また、以下のように実行キューにさらにスレッドが表示されます。

while true; do ps -eTo psr,user,pid,tid,cputime,class,rtprio,ni,pri,pcpu,stat,wchan:14,args | grep ZAG | grep ' Rl' | wc -l; sleep 0.5; done

その結果、CPU 使用率が少し上がり、より多くのスレッドが実行されます。しかし、負荷平均が上がってもCPU使用量は増えないようです。ディスクI / OまたはネットワークI / Oに関しては、常にほとんど発生していません。この事態の間、SARデータは大幅に増加しなかった。メモリ使用率は増加せず、システム全体のプロセス約1700のうち、プロセスの数がわずかに増加する可能性がありますが、それはすべてです。この間、cronでは何も起こりません。 htopまたはtop出力は、現在、一部のCPU使用率(主にユーザーCPU)が実際に発生していることを示しています(topでは、システムCPUが5%未満であると報告しています)。したがって、データを待つことは何もないようです。

私は/proc/interruptsに異常な点を見つけませんでした。スケジュール調整の中断はひどいようですが、偶数および奇数NUMAノードを含む6つのコアを確認してみると、プロセッサあたり1秒あたり1400程度で安定しているようです。

これはハイパースレッディングがオンの16コアマシン(E5-2667 v4プロセッサ)です。これには、それぞれps -efとps -eTfで表される36のZAGプロセスと729のZAG Theradがあります。

それで気になりました。私のCPU使用率はなぜそんなに低く、負荷平均はそんなに高いのでしょうか? 36個のZAGプロセスのうち700を超えるスレッドがあり、そのうちの1つがまだsched_yield()実行キューにありますが、CPUを蓄積していないためですか?それとも、sched_yield()もう実行できませんが中断できない状態ですか(下記参照)。

ブレンドン・グレグによるとhttps://www.brendangregg.com/blog/2017-08-08/linux-load-averages.html「負荷平均がLinuxで最初に登場したときは、他のオペレーティングシステムと同様にCPUの需要を反映しました。ステータスは次のように使用されます。ブロックされたタスクやディスクI / Oのいくつかのロックを含む信号の中断を避けるコードパス... 1993年には存在しなかったTASK_UNINTERRUPTIBLEを使用する新しいコードパスが原因であると推測されます。いくつかのロックプリミティブを含むTASK_UNINTERRUPTIBLEを設定する約400のコードパスがあり、これらのコードパスの1つはロード平均に含まれてはいけません...

ベストアンサー1

見つけたと思います。

質問は簡単です。

負荷の高い平均(つまり、実行キュー内の多くの項目)と低いCPU使用率を説明する方法は?

私はその答えが sched_yield() システムコールにあると信じています。スレッドが他のスレッドに譲歩している場合、そのスレッドはCPUの実行キューに残りますが、多くの操作を実行できない可能性があります。

バラよりhttps://books.google.com/books?id=9yIEji1UheIC&pg=PA370&lpg=PA370&dq=sched_yield+reli[… ]&hl=en&sa=X&ved=2ahUKEwimrNvwqrL1AhWIhOAKHQLyBDcQ6AF6BAgCE​​ AM

リンクが消えた場合:BovetとCesatiの第2版「Linuxカーネルについて」370ページ。

sched_yield() システムコールを使用すると、プロセスは中断されずに自発的に CPU を放棄できます。のプロセスは実行される機会があります。この呼び出しは主に sched_fifo プロセスで使用されます。

ここでは彼らは「プロセス」に言及していますが、マンページにはあります。https://man7.org/linux/man-pages/man2/sched_yield.2.html説明には、「sched_yield()は呼び出しスレッドがCPUを放棄します。スレッドは静的優先順位のためキューの終わりに移動し、新しいスレッドの実行を開始します」と示されています。

したがって、概念的には私たちは同じ振る舞いをします。つまり、実行キューリストの最後に到達します。我々が見たことによれば、スレッドがtask_running状態を維持することは合理的です。

おすすめ記事