概要
- 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 の熱管理は依然として開発・運用上の重要課題