ハクソク

世界を動かす技術を、日本語で。

Macのサーマルスロットリングを知るためのmacOSアプリの構築

概要

  • MacThrottle開発のきっかけと背景
  • Apple Silicon Macでのサーマルスロットリング問題
  • サーマル状態のプログラム的取得方法の模索
  • macOS内部APIや通知システムの技術的調査
  • SwiftUIによるメニューバーアプリ実装の流れ

MacThrottle開発ストーリー

  • M2 MacBook Air使用時、外部4K 120Hzディスプレイ接続で動作遅延や反応鈍化を体感
    • ファンレス設計のためサーマルスロットリング発生時も音で気付けない
    • iStat MenusMX 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.thermalStatepowermetricsの状態対応表(実測例)
    • 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の熱管理は依然として開発・運用上の重要課題

Hackerたちの意見

いい仕事みたいだね。聞いたところによると、MacOSでの開発は年々難しくなってるらしい。でも、その意味はちょっと疑問だな。自分の設定がサーマルスロットリングを引き起こしてるかどうかを知るのは大事かもしれないけど、それに対して何ができるの?ファンのプロファイルをいじることもできないし。アンダーボルトとかできるの?
寒い場所に移動するか、部屋の温度を下げるしかないね。
> でも、それに対して何ができるの? MacBookのファンがあるやつでは、iStat Menusでファンカーブを調整し始めたよ。デフォルトのカーブが遅れてて、ファンが最大速度に達する前にサーマルスロットリングが始まってたからね。特にApple Siliconについては、最近「ハイパワーモード」があることを発見したよ。これでファンがより高い速度で回るようになるんだ。だから、もうカスタムファンカーブは使ってないけど、すごく助かったよ(ただ、14インチのM4 Maxだと結構うるさいけどね)。MacBook Airの場合は、閉じるか、MacBookを持ち上げてファンを当てるくらいしかできないかな…ちょっと絶望的だね!
このアプリが存在してほしかったんだ。今、実際にある!時々、プロセスが変になってサーマルスロットリングに直面することがあって、その時はそれを殺すだけなんだけど、まず気づかなきゃいけない。バッテリーが半分なくなるまで気づかないことが多いんだよね!
> でも、それに対して何ができるの? 多分、いくつかのアプリを終了させることだね。バックグラウンドで動いてるアプリがたくさんあって、まだ閉じるのを面倒に思ってることが多いんだ。それに、忙しいループにハマってるソフトを検出するのにも良さそうだね。あとは、ちょっとお茶休憩を取って、落ち着くのを待つとか。
> でも、それに対して何ができるの? 環境によるね。昔、MacBookを使ってた時はファンがあったけど、新しいやつは全部パッシブだと思う。だから、その下の表面(またはそれがないこと)が一番重要になるんじゃないかな。膝の上に置いたり、毛のあるブランケットの上に置いたりすると、石のテーブルの上に置くよりも熱を逃がすのに効果的だよ。編集:AirとProのパッシブ/アクティブ冷却の分け方は今でも当てはまるみたいだから、Proを持ってるならファンの性能や吸気/排気をチェックするのが一番いい方法だね。
数年前にMac M1を手に入れてから、Macs-Fan-Controlを使ってるけど、めっちゃいいよ。CPUコアの値に基づいてファンのRPMをコントロールできるんだ。負荷がかかる時に90℃以上になっちゃうから、もっと保守的な値でファンを上げるように調整したよ。 https://github.com/crystalidea/macs-fan-control
Macbook ProでTG Proを使って自動で冷却してるんだけど、Appleがファンを回す前にMacを焦がすまで放置するのがマジでイライラする。
メニューバーにCPU使用率を表示させて、それを監視すればいいよ。CPUと全体のシステムワット数を表示させてるから、何かおかしいことがあったらすぐわかる。 https://github.com/exelban/stats
そうそう!最初にサーマルスロットリングだと疑ったのは、iStat MenusでCPU使用率が高いのにワット数が下がってるのを見たからだよ。
サイトがアクセス集中で死にそうだね、リポジトリはここだよ: https://github.com/angristan/MacThrottle
おっと、直したよ。ブログの前にCloudflare Workersがあって(Cloudflare Pagesにあるんだけど)、なぜかフェイルクローズモードになってたみたいで、フェイルオープンじゃなかった :(
彼がそれをHomebrewに入れれば、無料でノータリゼーションとコード署名がもらえるよ。そういう配布方法で手に入れたいな。
ほんとに?今日学んだ、アプリの開発者に依存してると思ってた。調べてみるね、ありがとう!
それはいいね。Windowsの署名を取得するための同じような無料の方法ってあるのかな?
2019年のMacbook Pro i9を持ってたから、サーマルスロットリングを判断する機能はすごく簡単に書けると思うよ: function isThermalThrottling() { return true; } 本当に、そのパソコンはほとんど好きだったけど、i9 CPUに高いお金を払ったのにi7よりパフォーマンスが悪いのはちょっとムカついた。
俺もその問題に悩まされたことある。特に外部モニターを2台接続してるとき。あんまりこのマシンが好きじゃなかったし、M1 Maxへのアップグレードはすごく大きかった。後でM3 Maxにアップグレードして、M1は誰かにあげようかなって思ってる。Appleシリコンのマシンは、長持ちするんじゃないかな。
俺はMid-2015のMacBook Proをi7で使ってたけど、常にファンをフルスピードで回してた(実際にはフルスピード以上)。それでファンがいくつか壊れたこともあったけど、それ以外はやってよかったと思ってる。
あのノートパソコンを持ってたけど、今までで一番最悪なコンピュータだった。起動するとすぐにファンが回り始めるし、Thunderboltデバイスを接続したり外したりするとカーネルパニックが起きることもあった。今はM1 MaxのMBPを使ってるけど、全く完璧だよ。
2019年のi9からこのコメントを書いてる。右側のポートから充電しないといけないんだけど、それがバカみたいだと思うけど、問題は解決した。どうしてそうなったのか全然わからないけど(たぶんどこかで読んだんだろうね)、数週間は本当にイライラしてた。確かにバカなことだけど。やっぱりmacOSの方がWindowsより好きだし、Logicでの制作ワークフローにもかなり投資してる。次はLinuxに移行するかもしれないけど、そのバカな変更をした後は、かなり使えるマシンになったよ。
すごいStack Overflowの投稿があって、AI検索では見つからないかも。i9のMacBook Proでの熱スロットリング(kernel_taskの使用)が、左側ではなく右側に電源を接続すると解消されたんだ。原因は、十分な冷却がないチップ(Thunderboltだと思う)だった。https://apple.stackexchange.com/questions/363337/how-to-find... i9のMacBook Proの下に静かなキャビネットファンを置けば、空気を引き抜いてかなり速く動くようになるよ。[1] それに加えて、キーボードの故障もあったから、ノートパソコンのキーボードの上にワイヤレスキーボードを置いて使ってた。ファンは下に置いてね。これが、Appleストアに保証修理に持って行ったときのやり方で、かなり大きな設計上の欠陥があることを指摘された。最速のMacBookを買うときは、正しい方法で冷却しないといけないのか、キーボードを使わない方がいいのか、空気中にほこりがあるかもしれないからって聞いたんだ。ノートパソコンは明らかにオーバースペックすぎた。i9のノートパソコンは、どんな状況でも適切に冷却できるように作られていなさすぎる。要するに、どのUSB-Cポートが電力を引き込んでいるのかを検出できれば、そのi9で何が起こるかをかなり正確に予測できると思う。M4 MaxのMacBook Proも同じ問題があると知って悲しい。ノートパソコンが厚くなっても、アップグレードしたいとは思わなくなったよ。[1] https://www.amazon.com/AC-Infinity-MULTIFAN-Receiver-Playsta...
https://github.com/macmade/Hot を見つけたよ。俺のIntel Macで動いてる :)
共有してくれてありがとう、今試してみるよ。先日、リサイクルショップで20ドルで2017年のiMacを見つけたんだけど、今のところすごく良い感じ。ただ、スロットリングが起きるかどうかはまだわからない。
> 熱制限がかかってるのは分かる。iStat MenusでCPU使用率が100%なのに、電力使用量が下がってるのが見えるから。別の可能性もあるよ。もしバッテリーが少なくて、間違って低出力のUSB-Cソース(スマホの充電器)に繋いじゃったら、CPU使用率が100%で電力使用量が低くて、パフォーマンスがひどくなることもある。多分、著者の問題じゃないけど、俺は何度も経験したことがある!このケースを検出する何かを追加する価値があるかもね。「システム情報」で充電器の電力が見れるはずだし、APIもあるんじゃないかな。
面白いね。iStat Menusは充電器のワット数を報告してくれる。時々、5Wや10Wの充電器でMacを充電してもその問題はなかった。でも、今思い出したけど、同僚が最近その問題を抱えてた気がする。なんでそんなことが起こるんだろう。
確かに何回かやったことあるけど、俺のMacBookの一台は、電源供給よりも多くの電力を引き出してた。特定のゲームをプレイしてたら、ノートパソコンが自動でシャットダウンするまで、約5時間しか遊べなかった。バッテリーから補助電力を引き出さないといけなかったから。確か次の世代のMacBookは、大きな電源アダプタが付いてきたんだけど、その経験から全然驚かなかった。それからGaNに切り替えて、アダプタのサイズを小さくしたんだよね。
> 熱制限がかかってるのは分かる。iStat MenusでCPU使用率が100%なのに、電力使用量が下がってるのが見える。これを読んで、"コア温度だけが熱制限の信頼できる指標じゃないのはなぜだろう?"って思った。熱コントローラーがある閾値を超えないように調整するために直接目指してる状態変数じゃないの?
M1のMacBook Airを使ってて、友達と週に一回のバーチャルD&Dセッションをやってる。4Kモニターに接続してるんだけど、それが原因だと思ってた。スライドショーみたいになっちゃって(アイスパックを下に置かないといけないくらい!)実はバッテリーの持ちが良すぎて、週に一度しか充電しないから、充電中にノートパソコンが熱くなりすぎてスロットリングしてたんだ。ちゃんとしたドックを使ってて100Wくらい供給できるから、充電不足ってわけじゃない。セッションの1、2時間前に充電し始めたら、問題が解決したよ。
次のMacBook Air M5には、ぜひAppleにバポーチャンバー冷却を使ってほしい。俺のMacBook Proでは、Appleが熱放散よりも低ノイズレベルを優先してるって結論に至った。ファンコントロールを使って、最低ファン速度に設定してるよ。
仮説:CPUの問題じゃなくて、USBコントローラーが熱を持ちすぎてるんじゃないかな。だからCPUやGPUが暴走するんじゃなくて、筐体が熱くなりすぎて通常の使用で熱放散ができなくなって、オーバーヒートしてスロットルがかかる。グラフでは100%になっちゃうのは、スロットリングで周波数が下がって、負荷が重くなってるからだと思う。他のアダプターやモニターも試してみて。
2019年のMBP i9の充電する側を変えたら、スロットリングの問題が効果的に解決したから、君の仮説は正しいかもしれないね。
`@_silgen_name`を使ってDarwinの通知APIを前方宣言した理由が気になるんだけど、`import Darwin`でそれらが使えるようにならないの?