借り初めのひみつきち

仮ブログです。

アクティビティモニターの作り方

MYOS や TOE にはアクティビティモニターがあります。

これらは見せ方が若干異なりますが、定期的にスケジューラーが集計したデータをそのまま表示しているだけです。

f:id:neriring16:20210311195817p:plain

f:id:neriring16:20210311200443p:plain

では、スケジューラーはどのように集計しているのでしょうか?

CPU時間

スレッドの切り替えのタイミングを知っているのはカーネルのスケジューラーなので、 スケジューラーが実際にスレッドを切り替える瞬間にシステムの時間を計測すればスレッドの実行時間を測定できます。

下の例のようなタイミングでスレッド切り替えをしたとします。(実際のOSは100倍〜1000倍くらい高速に切り替えます)

時間 切り替え
0秒 起動してスレッドAを実行
5秒 スレッドA→Bに切り替え
10秒 スレッドB→Cに切り替え
20秒 スレッドC→Aに切り替え

まずはスレッドAからBに切り替わるときシステム時間が 5 - 0 = 5 秒経過していたのでスレッドAの実行時間は 5 秒、次にスレッドCに切り替わるときも 10 - 5 = 5 秒経過しているのでスレッドBの実行時間は5秒、最後にスレッドCからAに戻ってきたときは 20 - 10 = 10 秒経過していたのでスレッドCの実行時間は10秒ということがわかります。

これらのデータを累算していくことで各スレッドが消費した CPU 時間がわかります。 また、ここで測定したデータが以降のデータの基になります。

各スレッドの CPU 利用率

各スレッドの CPU 利用率は時間の経過とともに変化する値で、一定の時間内にそのスレッドが利用した CPU 利用時間の割合に等しくなります。

先述の CPU 利用時間の累積値を一定の時間ごとにリセットすると、そのスレッドが一定時間のうち実際に実行された CPU 時間がわかります。 これを % で表示したものが各スレッドの CPU 利用率になります。 MYOS や TOE では1秒ごとに集計する専用のスレッド (Statistics) があります。

システム全体の CPU 利用率とアイドル率

他のすべてのスレッドが待機状態のときに HLT 命令を実行して CPU を休ませる専用のスレッドをアイドルスレッドと言います。

アイドルスレッドが実行されている時間は CPU が休んでる時間で、アイドルスレッドが実行されていない時間は CPU が忙しい時間ということになります。 つまり、アイドルスレッド以外のスレッドの CPU 利用率の合計がシステム全体の CPU 利用率になります。

なお、システム全体の CPU 利用率とアイドルスレッドの CPU 利用率を合計すると理論上 100% になるはずですが、集計のタイミングや細かい誤差などによって若干ズレが発生します。

CPU コアごとの CPU 利用率

MYOS は SMP に対応しているのでコアごとの CPU 利用率も計測できます。

MYOS ではコアごとにコア専用のアイドルスレッドがあります。 それぞれのアイドルスレッドとコアが 1:1 で紐づいているので、各アイドルスレッドの CPU 利用率がそのままコアごとのアイドル率になり、それを 100% から引いたものがそのコアの CPU 利用率ということになります。

また、マルチコア環境ではシステム全体の CPU 利用率の合計が 100% を超えることになりますが、 MYOS のアクティビティモニターでは平均値を表示しているので 100% を超えることはありません。

CPU 利用率グラフ

以上の情報を定期的に収集してグラフを描画すれば利用率のグラフになります。

いかがでしたか?

このように集計することで、それぞれのスレッドの負荷を測定したりスケジューラーが正しくスケジューリングしているか確認することができます。

なお、 TOE は時間計測に PIT を利用しているので精度が低い (1ms) ですが、 MYOS は HPET を利用しているので TOE よりもかなり正確に (1us) 測定することができます。