Macのサーマルスロットリングを知るためのmacOSアプリの構築
110日前原文(stanislas.blog)
概要
- MacThrottle開発のきっかけと背景
- Apple Silicon Macでのサーマルスロットリング問題
- サーマル状態のプログラム的取得方法の模索
- macOS内部APIや通知システムの技術的調査
- SwiftUIによるメニューバーアプリ実装の流れ
MacThrottle開発ストーリー
- M2 MacBook Air使用時、外部4K 120Hzディスプレイ接続で動作遅延や反応鈍化を体感
- ファンレス設計のためサーマルスロットリング発生時も音で気付けない
- iStat MenusやMX Power GadgetでCPU使用率100%・消費電力低下を確認
- 14インチM4 Max MacBook Proでもサーマルスロットリング発生
- 14インチ筐体の熱容量不足による制約
- 過去のM1 Proモデルではファン音すら聞こえず
- Apple Siliconの性能・省電力性は依然高評価
サーマルスロットリング検出方法の探求
- ProcessInfo.thermalState(Foundation API)利用でサーマル状態取得可能
- 例:
swift -e 'import Foundation; print(["nominal", "fair", "serious", "critical"][ProcessInfo.processInfo.thermalState.rawValue])' - しかしpowermetrics(root権限必要)と状態の粒度が異なり、情報の一致性に課題
- 例:
- ProcessInfo.thermalStateとpowermetricsの状態対応表(実測例)
- nominal → nominal
- fair → moderate/heavy
- serious, critical → trapping, sleeping(未到達のため未確認)
- 実際にはpowermetricsのmoderateでMac本体が発熱、heavyでスロットリング開始
- ProcessInfoでは両方ともfairに分類され実用性に乏しい
macOS内部通知システムの利用
- thermaldがサーマル状態をnotifyd(Darwin通知システム)へ通知
notifyutil -g com.apple.system.thermalpressurelevelで現在のサーマルレベル取得可能- レベル定義は
OSThermalNotification.hに記載- nominal, moderate, heavy, trapping, sleeping
- Swiftで通知システムからサーマル状態を取得するサンプルコード
- サードパーティ製ツールやroot不要で安全かつ簡便
MacThrottleアプリの実装
- SwiftUIでメニューバー用アプリを作成
- MenuBarExtraシーン利用でメニューバー表示
- アイコンは温度計デザイン、状態に応じて色変化(緑→赤)
- Dockアイコン非表示設定はInfo.plistのLSUIElementをtrueに
- 初期実装はpowermetrics利用のためroot権限補助スクリプトを用意
launchdデーモンとしてbashスクリプト常駐・状態をファイル出力- アプリはこのファイルを定期的に読み込み
- thermald通知利用に移行後はroot不要、アプリ単体で動作
温度・ファン情報表示の工夫
- 温度・ファン回転数グラフ表示も実装
- IOKitの非公開APIでは取得温度が低すぎる問題
- Stats(iStat Menusオープンソース代替)を参考にSMC経由の取得に切替
- SMCはSoCごとにキーが異なり、安定性や互換性に注意
- 例: M1, M2, M3で異なるキー配列
技術的考察とまとめ
- macOSでのサーマル情報取得はAPIごとに粒度や仕様が異なる
- notifyd通知経由での取得が現状最も実用的かつ安全
- SwiftUIとmacOS標準機能活用でシンプルなユーティリティ開発が可能
- Apple Siliconの熱管理は依然として開発・運用上の重要課題