バッテリーの power_now は信用できない - energy_now で本当の消費電力を測る

2026-09-24

ノート PC の消費電力を調べようとして /sys/class/power_supply/BAT0/power_now を見ると、妙なことに気づく。

CPU に負荷をかけても、数値がほとんど動かない。

この機体では、アイドルでも全力負荷でも 約 8.6W のあたりをうろうろする。これでは「8スレッド回したら何W増えたか」なんて分からない。最初は「省電力が効いているのか」と思ったが、そうではなかった。power_now が信用できない値だったのだ。

結論を先に書く。

なぜ power_now が嘘になるのか

power_now はドライバやファームウェアが計算して出す値で、ハードによっては電流・電圧の計測ではなく、いい加減な推定を返す。この機体(HP OmniBook、AMD)がまさにそれで、負荷に追従しない。

一方 energy_now(バッテリー残量、単位は µWh)は、実際に減っていく残量そのもの。これを時間で割れば、本当の平均消費電力になる。

正しい測り方

energy_now を一定時間あけて2回読み、差分を時間で割る。

BAT=/sys/class/power_supply/BAT0
e1=$(cat $BAT/energy_now); t1=$(cut -d. -f1 /proc/uptime)
sleep 120
e2=$(cat $BAT/energy_now); t2=$(cut -d. -f1 /proc/uptime)

# P[W] = ΔE[µWh] * 0.0036 / Δt[s]
awk -v e1=$e1 -v e2=$e2 -v t1=$t1 -v t2=$t2 \
  'BEGIN { printf "%.2f W\n", (e2-e1)*0.0036/(t2-t1) }'

時間に date(実時刻)ではなく /proc/uptime(起動時間) を使うのがポイント。この機体の実時刻はスリープをまたぐと正しく進まないため、CLOCK_BOOTTIME を使う。

落とし穴: 量子化

energy_now10mWh(10000 µWh)刻みでしか動かない。つまり短時間の計測では、差分が1目盛しか進まず精度が出ない。

たとえば 5W で 10秒測ると、動くのは 0.014Wh = 1.4目盛。誤差が 70% にもなる。目安として2分以上測ると安定する。不確かさは「1目盛 ÷ 計測時間」で見積もれる。

実測結果

power_now が約 8.6W で固定されていたのに対し、実際はアイドル 5.7W から負荷 22.8W まで、4倍の幅で動いていた。これを知らずに「電力を見て最適化」すると、嘘の数値を追いかけることになる。

まとめ

「電力を見て省電力化する」なら、まず正しく測ることから。