- MacThrottle は、Macが過熱により性能を制限しているときに、その状態をメニューバーで視覚的に知らせる SwiftUIベースのアプリ - オープンソース
- macOSの
ProcessInfo.thermalState API と powermetrics コマンドを比較し、システムの実際の熱状態を正確に検知する方法を探る
- 最終的に
thermald が Darwin の notifyd システムに投稿する通知 を活用し、ルート権限なしで熱状態を読み取る方式を実装
- アプリには 温度・ファン速度グラフ、状態ごとの色分けアイコン、macOS通知機能 が含まれ、ログイン時の自動起動にも対応
- Apple Silicon Macの 熱管理状態をリアルタイムで把握 できるツールとして、開発者やパワーユーザーに有用な診断手段を提供
Macの熱スロットリング問題を認識
- M2 MacBook Airで外部4K 120Hzディスプレイを使用すると、性能低下と応答遅延 が発生
- ファンがないため騒音では検知できないが、CPU使用率が100%の状態で電力使用量が低下
- iStat Menus と MX Power Gadget により、CPU周波数と電力の低下 を確認して熱スロットリングを診断
- M4 Max MacBook Proでも同様の現象が発生し、14インチモデルの 熱設計上の限界 による問題と言及
- Apple Siliconの電力効率は依然として高いが、熱状態を直接検知する方法 を探したい
macOSで熱状態をプログラムから確認する
- macOSは複数の方法で熱状態を公開しているが、一貫性に欠ける
- Appleが推奨する方法は、
Foundation の ProcessInfo.thermalState を使うこと
- 出力例:
nominal, fair, serious, critical
- ルート権限が必要な
powermetrics -s thermal コマンドでも同様の情報を得られるが、
両者では 状態の区分単位が異なる
- 例:
fair は powermetrics の moderate と heavy の両方を含む
- 実際にスロットリングが始まる時点は
powermetrics では heavy と表示されるが、ProcessInfo では区別できない
thermald と Darwin通知システムの活用
powermetrics のデータは thermald デーモン から取得され、
thermald は現在の熱圧力状態を notifyd システムイベント として公開している
notifyutil -g com.apple.system.thermalpressurelevel コマンドで状態を確認可能
OSThermalNotification.h ヘッダーで定義されている熱圧力レベル:
nominal, moderate, heavy, trapping, sleeping
- Swiftコードから
notify_register_check と notify_get_state を呼び出し、
ルート権限なしでリアルタイムの熱状態を読み取る機能 を実装
MacThrottleアプリ開発
- SwiftUI と MenuBarExtra を使って、メニューバー専用アプリを制作
- 温度計アイコンの色で状態を表示(緑→赤)
Info.plist の LSUIElement を true に設定して Dockアイコンを無効化
初期アプローチ: powermetrics ルートヘルパー
- 当初はルート権限が必要な
powermetrics を使うため、
LaunchDaemon と bashスクリプト でヘルパープロセスを構成
/usr/local/bin/mac-throttle-thermal-monitor が10秒ごとに状態を /tmp ファイルへ記録
- アプリはそのファイルを定期的に読み取って表示
改善: thermald IPC通知の利用
温度とファン速度の表示
- CPU/GPU温度とファン速度をグラフ表示
- 初期には IOKitの非公開API を使った際、温度が実際より低く表示された(約80°C)
- オープンソースの Stats プロジェクトを参考に、SMCインターフェース へ移行
- SoC世代ごとに異なるキー(
Tp0D, Tf0E など)を使う必要がある
- SMCが動作しない場合は IOKit にフォールバック
メニューバーグラフの実装
- グラフは3種類の情報を同時に表示
- 背景色: 熱状態(緑〜赤)
- 実線: CPU温度
- 点線: ファン速度比率
- 2秒間隔でデータを収集し、10分単位の履歴 を維持
onContinuousHover でツールチップを提供し、
.drawingGroup を追加して GPUレンダリングにより120Hzディスプレイでも滑らかに表示
macOS通知と自動起動
- 熱状態の変化時に 通知送信機能 を追加
SMAppService API により、ログイン時の自動起動設定をサポート
register() / unregister() / status メソッドで制御
配布と利用
- Apple Developerアカウントがないため、正式な公証(notarization) は不可
- GitHub Releases からインストールする場合、
Privacy and Security で手動承認が必要
- 一部のMacでは Xcodeで直接ビルド しないと実行できない
- インストール方法とビルド方法は GitHub README に記載
結論
- MacThrottleは、Apple Silicon Macの熱スロットリング状態をリアルタイム監視 できる軽量ツール
- ルート権限なしで動作し、視覚的フィードバック・通知・グラフ機能 によって
開発者や高負荷作業ユーザーに システムの熱状態認識 を提供
1件のコメント
Hacker Newsの意見
2019年モデルのMacBook Pro i9を使っていたが、熱スロットリング検知関数はこんなふうに簡単に書けそう
冗談だけど、高価なi9 CPUを買ったのにi7より性能が低いのはかなりがっかりだった
理由は分からないが、そうするとスロットリングが消えた
それでもmacOSとLogicベースのワークフローに慣れているので使い続けている
Linuxに移ることもできるだろうが、今でもかなり使えるマシンだ
外部モニター2台とAdobe Creative Suiteを使うたびにスロットリングがひどかったが、このパッドで解決した
欠点は底面が熱くなって膝の上に置きづらくなることだが、まったく後悔していない
今はM3 MacBook Air(24GB RAM) に買い替えて非常に満足している
まだ2019モデルを使っている人なら、ぜひVRMサーマルパッド改造を検討してみてほしい
Dellでもi9をi7に替えた途端、ずっと良くなった
「大きい数字 = より良いCPU」というマーケティングに騙されたようなものだ
その後M1 Maxに替えたら完全に別世界だった
今はM3 Maxにアップグレードしていて、Apple Siliconは長く使えそうだ
起動直後からファンが回り、Thunderbolt機器をつなぐとカーネルパニックもしばしば起きた
今使っているM1 Max MBPは完璧に安定している
プロジェクトはかなり良さそうに見える
ただ、macOSでは開発がどんどん難しくなっていて、スロットリングを検知しても実際に何ができるのかは疑問だ
ファン速度の調整もできないし、アンダーボルティングも不可能では?
デフォルトのカーブが遅すぎて、先にスロットリングが発生していたからだ
Apple SiliconではHigh Power Modeを使うとファンがより速く回る
今はカスタムカーブは使っていないが、14" M4 Maxではかなりうるさい
MacBook Airにはファンがないので、ただ冷ますしかない
デフォルト設定だと90度以上まで上がるので、もっと保守的に設定した
GitHubリンク
ときどきプロセスが暴走してスロットリングが起きるのに、それに気付くまでにバッテリーが半分くらい減っている
バックグラウンドで動いているアプリが多いと、こういう問題がよく起きる
Homebrewに入れれば無料でコード署名と公証を受けられる
そうやって配布されると本当にいいと思う
私の仮説ではCPUの問題ではなく、USBコントローラが熱を飽和させているのだと思う
CPU/GPUではなく筐体が過熱して放熱が妨げられ、最終的にスロットリングが起きる構造のようだ
別のアダプタやモニターで実験してみる必要がある
あなたの言う通りだと思う
4K 144Hzモニターに接続してZoomや動画ストリームをいくつも開くと発熱がひどくなる
USBコントローラというより、単純に負荷が大きいせいのように思う
サイトはトラフィック急増で落ちたようだ
リポジトリは angristan/MacThrottle
iStat MenusでCPUが100%なのに消費電力が低いとスロットリングだと考えられるが、
低出力のUSB-C充電器に接続されている場合にも同じ現象が起きる
充電器の電力を検知する機能を追加するとよさそうだ
充電中で熱くなってスロットリングがひどかったが、セッション前にあらかじめ充電しておいたら解決した
その後の世代でより大きい電源アダプタが出た理由が理解できた
温度こそが直接の制御変数ではないのか?
CPU使用率とシステム電力をメニューバーに表示しておけば異常の兆候にすぐ気付ける
exelban/stats
CPU使用率は高いのに電力量が下がっているのを見て気付いた
次のMacBook Air M5にはVapor Chamber冷却が入ってほしい
今はAppleが放熱よりも騒音最小化を優先しているように見える
そのためファンの最低速度を強制的に上げている
筐体が環境と熱平衡に達すると、放熱量は限界に突き当たる
ファンがあれば銅板と風で十分に解決できる
結局はエネルギー保存の問題だ
thermal pressure通知のバグがあるようだ
アプリでその問題に遭遇したことがあるか気になる
関連Issue
ProcessInfo.processInfo.thermalStateを使ったときに状態が更新されないのを見たでも、今使っているthermald通知方式ではそういう問題はない
なぜ
@_silgen_nameでDarwin APIを直接宣言したのか気になるimport Darwinではアクセスできないのか?import DarwinだけではそのAPIは公開されていないようだ