あけましておめでとうございます。
先日、テレビを見るための地デジ/BS/CSチューナーを繋いでチューナーサーバーにしていたマシンを、
Core i5-2410Mの半壊ノートPCから、Core i5-9500Tの中古ミニPCに移行しました。
NECのMate MKM22/C-5というモデルです。
中身的にはLenovoのThinkCentre M920q Tinyとほぼ同等品のようです。
ミニPCの稼働時間自体は短いため、半分ぶっ壊れたノートPCよりは保つだろうと思って安心してました。
そしてしっかりテストもせずにEPGStationやらの設定を変えて、年末の紅白とか歌番組の録画予約をバンバンぶち込みました。これが悲劇の始まり。
大晦日、紅白の途中でお風呂に入らなければならず、録画してるし・・・と思ってさっさと入浴して追っかけ再生しようと思ってVLCで開いたら
「終わった。」これしか言葉が出ませんでした。
あわてて他の録れてる部分にシークしてもみーんなこんな感じ。写真載せるのにもはやモザイク不要です。
原因調査
まず、この時点でチューナーは2個開いていました。2番組同時録画していたってことです。
①電源供給不足を疑う
チューナーはTHUNさんの外付けキット
を使ってポータブル化しており、USBケーブル1本で内蔵のライザーカードに電源を供給していました。
推奨電源が5V/3Aで、一般的なPCのUSBポートは0.5A、多くて1.0A(充電に特化していれば2.4Aぐらいだけどほとんどない)なので、供給不足・・・?と思ったのです。
しかし、以前の環境でも500mAしか出せないUSBポートに挿して使っていて、5チューナー開いてもドロップしないことを確認していました。
電源供給不足はないと考えました。
②USBポートを疑う
チューナーの不具合のよくある事例として、USB3.xポートに挿していたということがあります。
しかし、MKM22/C-5にはUSB2.0のポートがありません。
たぶん違う…と思いながら別のことを考えました。
③ローカルネットワークを疑う
最近Wi-FiルーターをバッファローのWXR9300BE6Pに変えました。
新しいWi-Fi規格がリリースされてから初期に登場するルーターはだいたい仕様が完璧に固まる前のDraft規格を使って実装しているため
ごくまれに相性問題が発生することがあります。
なので作業PCのWi-Fi接続をいろいろ調べましたが安定してそうでした。
本当の原因: Intel C-State
さらに調査をするため、GitHubからソフトを下ろして自前ビルドしていました。
その時たまたま作業用PCでTVTestで2チューナー開きっぱなしにしていました。
コンパイルが始まったタイミングで、ドロップが収まったのです。
「え?」と一瞬思いましたが、i5-9500「T」だからすぐ理解しました。
Intelのプロセッサ電力管理機能である「C-State」が悪さをしていたんです。
C-Stateは、CPUがあまり仕事をしていないときにクロック周波数を抑えたり、CPUを休眠状態に入れたりして待機電力を減らそうとします。
ノートパソコンにCPUを搭載する場合にはこういう機能がないとバッテリーがあっという間になくなります。
C-Stateには10段階ぐらいのレベルがあって、C1からC8まであるんだそうです。数字が大きくなるほどCPUが深い眠り(ディープスリープ)に入って復帰に時間がかかるそうです。
この「復帰に時間がかかる」がドロップの原因になっているのではないかと予想しました。
チューナーサーバーにはまったくと言っていいほど負荷がかかっていません。
チューナーを開いてストリームを読む場合も、ほとんどCPUに負荷はかかりません。
そのため、C-Stateが「CPUが暇している」と判断して消費電力を抑える段階に入ってしまった可能性があります。
CPUがスリープする→起きるを繰り返していて不安定な感じになっていた。
コンパイル時にドロップがなくなったのはCPUが使われていてアクティブ状態になっていたから、そう考えると辻褄が合います。
C-Stateを無効化する (非推奨)
ならばと、C-Stateを無効にして解決するか確認してみます。
OSはUbuntu Server 24.04 LTSを使用しています。
Linuxではintel_idleというカーネルドライバーがあり、起動時にパラメータを指定してあげるとC-Stateの設定を変えられます。
ブートローダーにGRUBを使用しているので、/etc/default/grub を編集します。
このファイルに GRUB_CMDLINE_LINUX_DEFAULT という変数があり、これを使って起動時にカーネルにパラメータを渡します。
GRUB_CMDLINE_LINUX_DEFAULT="intel_idle.max_cstate=0"これで、消費電力の管理に関する機能が無効になります。
編集したら、update-grub をroot権限で実行します。
sudo update-grub
ここまでできたら、再起動します。
すると、ドロップしなくなりました!!
複数チューナー開いて1分ぐらい放置してもドロップしなくなりました。安心。
デメリット発見
しかしここで異変に気づきます。
CPU使ってないのに常にCPUが20W近く食っています。しかも発熱もすごい。
C-Stateを無効化したことにより、低負荷時の消費電力を抑える機能がなくなりました。
常にCPUが全速力で動いていることになります。
これでは電気代がえらいことになります。
ドロップしないC-Stateレベルで運用する (結論)
せっかく省電力モデルなんだし、使ってないときは消費電力が下がってほしいものです。
C-Stateについてもう少し詳しくしらべるため、嘘か本当か、Google Geminiに聞いてみました。
| レベル | 名称 | 動作状況 | 内容・効果 | |
|---|---|---|---|---|
| C0 | Operating | 稼働中 | CPUがフル稼働している状態。省電力機能は働いていません。 | |
| C1 | Halt | 停止開始 | 命令の実行を停止。回路の大部分は維持されるため、瞬時に復帰可能です。 | |
| C1E | Enhanced Halt | 電圧抑制 | C1の状態に加え、電圧とクロック周波数も下げて消費電力をさらに抑制します。 | |
| C3 | Sleep | キャッシュ維持 | L1/L2キャッシュの内容は保持しますが、内部クロックを停止させます。 | |
| C6 | Deep Power Down | 電圧カット | プロセッサのコア電圧をほぼゼロにします。復帰には時間がかかりますが、劇的に節電できます。 | |
| C7 | Deepest Sleep | キャッシュフラッシュ | L3キャッシュの内容をメモリに書き出し、コアを完全にオフにします。ノートPC等で重要です。 | |
| C8~C10 | Ultra-Deep Sleep | 超省電力 | 近年のモデル(Haswell以降)で導入。ほぼすべての電圧供給をカットし、待機電力を極限まで減らします。 |
本当か・・・?
これを信じるなら、復帰に時間がかからないC3ぐらいならドロップしない?
実際にmax_cstateを変えながら実験してみました。
intel_idle.max_cstate の値を 1、3 と変えていきます。
結果は、C3までなら無難そうでした。
消費電力も低負荷時は1W程度に抑えられ、良さそうです。
消費電力問題が解決したのでC3より下は試してません。時間があったらやってみます。
まとめ
ということで、まさかのC-State問題にぶち当たりました。
低負荷すぎて逆にリアルタイム性が求められるシーンでもたつくというのは初めてのケースです。
まぁ普通のデスクトップ用CPUを使えよって話なんですがね…