banner
 Sayyiku

Sayyiku

Chaos is a ladder
telegram
twitter

pmset 電源管理讓 Macbook Pro 乖乖小憩

自從 M1 芯片的 macbook 買到手,搁著不用總是一周就沒電了。昨晚充滿觀察了一下,一夜合蓋休眠竟然消耗了 10% 的電。

TL;DR: 執行 sudo pmset -b powernap 0 關掉小憩,一晚上合蓋 1% 都沒掉。

消失的小憩#

在 MacBook 的電池設置(桌面機叫「節能」)裡一直有兩個開關:

  • 喚醒以供網絡訪問
  • 啟用電能小憩

這倆的具體含義在官方支持上可以找到,簡單來說:

  • 喚醒以供網絡訪問:當電腦被訪問時允許喚醒以提供服務。比如向外共享打印機或文件。同時也會定期喚醒來廣播文件更新通知(如果啟用了文件共享的話)。注意,這個選項的意思不是「喚醒來讓本機的程序可以聯網更新」。
  • 小憩:睡眠時允許喚醒來更新自身的數據,例如郵件、iCloud 同步以及時間機器。

那麼這兩個選項各自的作用應該可以整明白了。在 macOS 12 的系統設置裡,只對「小憩」做了解釋,還算清晰。可是 macOS 13 增加了對「喚醒以供網絡訪問」的解釋,用詞非常迷惑,並且 m1 芯片的設備不再顯示「小憩」的開關

image

從上圖可以看出,macOS 13 中對「喚醒以供網絡訪問」的解釋非常類似小憩,給人一種這兩個選項合併的假象。根據這個解釋,可以理解為:關掉網絡喚醒,就不會在後台更新數據了。然而事實是,無論關不關「網絡喚醒」,「小憩」始終是打開的,休眠時始終進行後台更新,這就是休眠耗電的元兇了。

感覺蘋果好心機啊,對 arm 芯片功耗太過驕傲,自以為是地默認開啟後台更新。為了不讓用戶找麻煩,還修改了另一個選項的描述讓你感覺可以關閉。看到網上有大量 m1 設備待機耗電的抱怨,各種分析最後也沒徹底解決。

pmset 電源管理#

pmset (Power Management Set) 是一個 macOS 的命令行電源管理工具,系統設置裡的相關選項與它想管理,不過 pmset 提供了更詳細的配置。

我怎麼認定「網絡喚醒」與「小憩」沒有合併的呢?在 pmset 中,「網絡喚醒」管理的是 womp,「小憩」關聯的是 powernap

注意,不同設備所支持的配置參數不同,很多參數比如 standbydelaylow/high 在 m1 設備上無效。大概還是因為蘋果的自信,就去掉這些細節的節電策略了。

配置查詢#

注意區分:

  • 睡眠 sleep:保持內存供電
  • 休眠 standby:內存數據寫入硬盤,內存斷電
  • hibernate:待機模式。強調的是進入待機這一操作(比如關閉蓋子),具體是睡眠還是休眠要看設置。

查詢當前生效的配置:

查詢用戶配置:

因為一些進程可能會阻止待機,這些會反映在當前生效的配置中,所以不一定與用戶配置相同。

給出一個對照表:

屬性單位備註系統設置 (macOS 13)
standby/autopoweroff*0/1允許從睡眠切換到休眠
powernap0/1電源小憩電池 - 選項 - 啟用電能小憩
networkoversleep0/1睡眠時如何處理共享網絡。不支持修改
disksleep分鐘關閉硬盤等待時間,0 為關閉
sleep*分鐘睡眠等待時間,0 為不睡眠
hibernatemode*0/3/25待機模式。0: 睡眠,25: 休眠,3: 先睡眠後休眠
ttyskeepawake0/1有活躍的 tty(終端會話)時不休眠
displaysleep分鐘關閉顯示器等待時間鎖定螢幕 - 不活躍時關閉顯示器
tcpkeepalive*0/1允許 tcp 連接
lowpowermode0/1省電模式電池 - 低電量模式
womp0/1允許網絡喚醒電池 - 選項 - 喚醒以供網絡訪問
gpuswitch0/1/20: 集成顯卡,1: 獨立顯卡,2: 自動
standbydelayhigh/low*從睡眠切換到休眠的等待時間
highstandbythreshold0-100剩餘電量超過這個數 standbydelayhigh 生效,否則 low 生效
proximitywake0/1登錄同一帳戶的設備靠近時喚醒

如果執行 pmset -g custom 發現缺少一些屬性,就是當前設備不支持。

這些屬性實際效果不能光看字面意思,很多時候是配合著用的,下面是幾個常見的注意事項:

  • sleep: 即使 sleep 計時器條件滿足也不見得一定會進入待機,比如「螢幕開啟」會阻止睡眠。需要所有條件都滿足才可以睡眠。m1 macbook 電池模式下默認 sleep=1,也就是說睡眠等待時間實際上由 displaysleep 控制。
  • hibernatemode:具體是否會把內存寫入硬盤還同時受到 standbyautopoweroff 的控制。
    • 0:僅睡眠,不會把持久化內存中的數據。若掉電則丟失未保存的數據。
    • 25:僅休眠。每次待機都持久化內存,並停止內存供電。重啟時從硬盤恢復內存。顯然喚醒時會慢一點。
    • 3:混合模式,先睡眠再休眠。
  • tcpkeepalive: 通過命令行關閉時有警告,會影響系統核心功能,比如 FindMyMac。實測開啟影響不大,只需關閉 powernap 足夠了。
  • standby/autopoweroff:這倆目前看作用一樣,只是出現的背景不同。standby 是在 macbook 上延長續航,autopoweroff 為了讓桌面機滿足歐盟節能要求,所以 macbook 沒有這個屬性。

修改配置#

執行 sudo pmset restoredefaults 可恢復默認。

修改配置需要 sudo 權限

修改配置命令格式為:

pmset [-a | -b | -c | -u] [setting value] [...]
  • -a: 對所有模式生效
  • -b: 對電池模式生效
  • -c: 電源適配器下生效
  • -u: UPS 供電下有效

pmset -g custom 的輸出沒有某些模式,就是設備不支持。

下面給幾個常用配置命令:

  • 電池下關閉小憩(推薦)sudo pmset -b powernap 0
  • 電池下禁止 TCP 連接(可能導致部分系統功能不可用): sudo pmset -b tcpkeepalive 0
  • 電池下待機時強制休眠(持久化內存,斷電): sudo pmset -b hibernatemode 25

喚醒分析#

查看從開機以來的睡眠 / 喚醒次數:

輸出的結果:

字段註釋
Sleep Count睡眠次數
Dark Wake Count後台喚醒次數(不亮屏)
User Wake Count亮屏喚醒次數(通常是用戶手動喚醒)

查看詳細後台喚醒記錄:

pmset -g log | grep -e "Wake from" -e "DarkWake" -e "due to"

比較難看懂

  • AOP.OutboxNotEmpty spu_queue_overflow_ep42: 1-2 小時一次是正常的

查看待機鎖:

有時系統或應用程序會阻止進入待機,這些運行時的臨時待機鎖稱為 assertions,它們會反映在實時電源配置裡 (pmset -g),也可以通過上面命令查詢。輸出如下:

Assertion status system-wide:
   BackgroundTask                 0
   ApplePushServiceTask           0
   UserIsActive                   1
   PreventUserIdleDisplaySleep    0
   PreventSystemSleep             0
   ExternalMedia                  0
   PreventUserIdleSystemSleep     1
   NetworkClientActive            0
Listed by owning process:
   ........

注意後面的數組代表對應鎖是否啟動,而不是鎖的個數。下面會顯示具體哪個進程啟動了鎖,以及是否有超時時間。通常 UserIsActivePreventUserIdleSystemSleep 這兩個鎖都是啟動的:

  • UserIsActive: 有個系統進程在判斷用戶是否活躍,超時 120 秒
  • PreventUserIdleSystemSleep: 有個系統進程因為螢幕已點亮而持有這個鎖,螢幕休眠後會自動釋放的。
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。