siltopは、Apple Silicon搭載MacのCPUや電力の状態を端末上で見るためのツールです。(固定版README)同じCPU使用率やW表示でも、何を基準に計算した値か、いつ更新された測定値かによって読み方が変わります。本稿では、数値を比較したりJSONログを集計したりする際に、先に確認しておきたい定義と制約を整理します。

補足:この記事の確認範囲

対象はsiltop v1.2.1の公開コードと文書で、参照コミットは c2dab6b584389587417a63121e7a7a174bb43da6 に固定しています。本稿では、Mac実機での動作確認や負荷測定を行っていません。本稿で扱うのは指標の定義と比較条件です。取得不能時の挙動も、固定版の公開実装に基づいて説明します。

CPUの割合は、稼働時間とクロックを分けて読む

CPUの稼働割合は、前回の採取から増えたCPU時間の合計に対して、CPUが処理を実行していない時間(idle)を除いた増分が占める割合です。

補足:CPU時間の取得方法

siltopのmacOS向け実装は、コアごとのCPU時間カウンターをMachの host_processor_info(PROCESSOR_CPU_LOAD_INFO)で取得し、前回との差分を計算します。初回の取得値は差分を計算するための基準として保持します。(CPU時間の取得と差分計算)

CPU見出しの scaled は、コア別の値を平均した近似値です。対応する周波数情報があるコアでは、稼働割合を最新の周波数比で重み付けします。(固定版のCPU集計)

周波数が欠測した場合は、利用できる情報とコアへの対応付けに応じて補完方法が異なります。コアのMHzをクラスターのMHzや最低MHzで補う経路がある一方、対応する周波数情報を割り当てられないコアでは、重み付け後の値に、稼働割合がそのまま残る場合もあります。(CPUの補完処理、コアの初期値)

補足:周波数を補う順序

対応する読み取りデータがあるコアは、reading.mhz、cluster.mhz、cluster.min_mhz の順に値を選びます。対応データがないコアには、同種の未割り当てクラスターの平均周波数比を使う経路があり、該当クラスターもなければ scaled の更新を省いて初期値の active を残します。周波数比は max(取得MHz, 最低MHz) / 最大MHz を0〜1に制限し、最大MHzが0の場合は1を使います。(周波数比の補正)

例えば、あるコアの稼働時間が50%、周波数比が50%なら、そのコアの重み付け後の値は25%になります。これは計算方法を示す仮の例です。CPUの稼働時間と、macOSの計測情報を読み出す仕組みであるIOReportから得る周波数データは、集計周期も異なるため、同じ観測窓の値とは限りません。(更新周期の違い)

クラスター行の負荷とクロックについて、READMEは「busy shareとclock」を表示すると説明しています。実装を確認すると、その負荷値には各コアの scaled を平均した値が使われています。表示を読む際は、READMEの呼び名と、実装が参照する値を対応づけます。(READMEの説明、展開CPUパネル)

JSONでは、全体の cpu.usage と cpu.scaled を分けて追えます。一方、プロセスの cpu_pct は100%が1コア分、200%なら2コア分に当たります。全体の0〜1の割合とプロセスの%では分母が異なります。(JSONのCPU値、プロセスCPU%の定義)

確認する値読み方併せて確認する点
cpu.usageCPU全体の稼働時間の割合、0〜1処理完了時間は別の指標
cpu.scaled周波数で重み付けしたコア平均、0〜1計算に用いるのは稼働時間と周波数比
プロセスの cpu_pct100%で1コア分全体の割合とは分母が異なる

Activity Monitorと対応づけるのは、プロセス一覧のCPU%とsiltopの cpu_pct です。作者のJSON仕様は、この値をActivity Monitorや top と同じ1コア100%の基準と説明しています。cpu.usage はMac全体の非idle割合、cpu.scaled は周波数で重み付けした全体値なので、どちらもプロセスCPU%とは別の指標として記録します。cpu.usage や cpu.scaled と比較する場合は、対象の範囲や周波数補正が異なります。ここで確認したのは仕様上の分母の対応です。同じ採取区間で実測していないため、Activity Monitorのプロセス値と cpu_pct に差が出た場合の原因は、本稿では特定していません。(作者文書のプロセスCPU%)

実務で同じ仕事を比較するときは、プロセス単位かMac全体かをそろえ、分母と採取区間を記録します。稼働時間の割合と周波数で重み付けした値、処理の完了時間・電力は別の指標として観測します。

画面の更新周期と、電力の計測区間を分ける

電力の取得元は項目によって異なります。システム全体の入力電力は、ハードウェアの管理情報を扱うSMC(System Management Controller)の PSTR から取得します。CPU電力では機種別のSMC電力項目を優先し、SMC側に値がないときはIOReportのCPU電力値を補完に使います。GPU・ANE・DRAMの電力もIOReportから取得します。(電力の取得元、CPU電力の補完)

IOReportのエネルギーからWを得る経路では、エネルギーの増分を、ドライバー側の公開タイムスタンプの差で割ります。計算にはドライバー側の時刻を使い、アプリの描画周期とは区別します。最初の公開で差分の基準を置き、W値を計算した後は、新しい公開がなければ直前の値を保持します。差分を計算できる新しい公開でエネルギー差分がゼロなら、計算結果はMeasuredの0 Wになり得ます。(差分計算と保持)

開発者がM5 Pro・macOS 27環境で記録したPMGRが管理する CPU Energy・ANE・DRAM・クラスターの項目の公開間隔には、2〜108秒の幅がありました。これは、その環境と項目についての記録です。この公開間隔を、GPUなど別経路や他機種にも共通する周期として扱えません。画面が1秒ごとに変わっていても、各Wが毎秒の新しい測定を表すとは限りません。(作者の公開間隔の記録)

保持・欠測・0 Wを混同しない

実装は、新しく得た値、前の公開値の保持、モデルによる推定を分けて管理します。保持値は公開から10秒を超えると、現在の電力として利用できなくなります。

補足:保持値を利用できる境界条件

実装では、10秒ちょうどの保持値は、有限のW値なら usable() の対象に残ります。10秒を超えたHeld値は利用できません。(保持値の失効条件)

電力パネルの ≈ は保持値または推定値を示します。保持値には、表示条件に応じて経過時間も付きます。このパネルでは0.05 W未満の値は表示対象になりません。画面上の省略だけでは、微小値の非表示か取得不能かを判別できません。JSONで記録する場合は、後述する個別電力フィールドの null と数値を区別します。(電力パネルの表示条件)

次の表は、IOReportのエネルギー差分による値と、その保持の扱いです。推定値やSMC由来の値とは経路を区別します。欠測を便宜的に0 Wへ置き換えることと、新しい公開の差分から0 Wを得ることは別です。

状態現在値としての扱い電力パネルでの読み方
新しい公開から計算した値Measuredとして扱う0.05 W以上を表示する
新しい公開のエネルギー差分がゼロMeasuredの0 Wになり得る微小値を省くため表示されない
有効な前回値を保持Heldも利用可能表示対象なら ≈ が付く
保持が10秒を超えたそのHeld値は利用不可そのHeld値を現在値として表示しない
まだ値を取得していないこの経路の値はないこの経路の値は表示できない

JSONでは時刻だけで鮮度を判定できない

JSONやNDJSONに記録される個別の電力フィールドでは、未計測・未収集の値は null、得られたゼロは数値の 0 として区別します。(nullと0の仕様)

この固定版は、利用可能な保持値も数値で出力します。一方、電力値ごとの取得元区分や経過時間はJSONに含めません。unix_ms は出力オブジェクトを作った時刻で、電力をドライバーが公開した時刻とは別です。(電力JSONの型、現在値への変換、出力時刻の定義)

そのため、NDJSONの行ごとに時刻が進んでも、毎行を独立した新しい電力測定として数えることはできません。

合計値の意味にも注意が必要です。sys_power はSMCの PSTR に由来するシステム全体の値ですが、all_power は取得できたCPU・GPU・ANEの部分合計です。3項目すべてが不明な場合は null になります。sys_power と all_power は対象の異なる値として記録します。(システム電力と部分合計)

単発の --json と継続出力の --json-stream は、どちらも最初の採取を初期化に使い、通常の更新間隔の待機を行います。単発の --json には、初回出力用の値を追加で採取するための待機処理もあります。この追加待機も、すべての電力項目がそろうことを保証するものではありません。(単発と継続出力の初期化)

対応機種と自己負荷の数値を、条件付きで判断する

プロジェクトはM1〜M5対応を掲げています。ただし、固定版の調査文書で実機から得たIOReportチャンネルデータが示されているのはM5 Proです。他世代の想定やテスト用データと、実機での確認範囲を分けて評価します。(対応の表記、実機データの範囲)

自己負荷の「CPU 1.34%」も、開発者がv1.2.0で報告した条件付きの測定です。M5 ProのMac17,8、macOS 27.0.1、AC接続、端末160×45、1秒間隔で20秒の測定窓を3回取り、中央値を使っています。割合は1コアを100%としたものです。同じ記録の既定500 ms間隔では1.70%でした。これらは作者によるv1.2.0の測定値として参照します。v1.2.1や他機種での負荷は、対象環境で確かめます。(作者の測定条件と結果)

導入を検討する方は、使用する機種で必要な項目が得られるか、CPU値の定義が目的に合うかを確認してください。記録を自動処理する際は、CPUの分母、電力の保持期限、null の扱いも集計条件として残してください。