RTX 4070 (12GB VRAM) を使ってるけど、Stable Diffusion やら Photoshop や DaVinci Resolve などを使うと非常にカツカツでアプリケーションを終了させたりしてしのいでいる。あとほんの少しVRAMがあれば……と思うことも多々ある。これらのアプリが共有メモリに侵食してくると劇的にパフォーマンスが落ちるので……

ふと iGPU を有効にして微妙に VRAM を使用する Chrome ベースのアプリや Chrome 自体を iGPU に持ってくれば、dGPU から多少の VRAM を節約できるのではないかと考えた。のでやってみることにした。なおメインメモリは余っているものとする。

iGPUを有効にする

これまで何も考えずに iGPU は無効にしていたので、まずは UEFI メニューから iGPU を有効にして再起動。メインディスプレイ以外は iGPU 側に接続しなおした。

そのうえで、アプリケーションごとの設定も、特にパフォーマンスが必要ないものは iGPU を使うように。これは設定 > システム > ディスプレイ > グラフィックスからアプリケーションごとに設定できる。

細かく VRAM 使っているプロセスを指定していく。というかデフォルトを iGPU にできればいい気がするが……

Intel ドライバのアップデート

Chrome がどうもちょくちょくブラックアウトするので、Intel のディスプレイドライバを最新に

https://www.intel.co.jp/content/www/jp/ja/download/864990/intel-11th-14th-gen-processor-graphics-windows.html

Windows における iGPU と dGPU

dwm.exe (デスクトップウィンドウマネージャ) がウィンドウの合成を担当しており、これが各ウィンドウの内容をテクスチャとして合成してディスプレイへ出力している。

あるアプリケーションが iGPU を使ってレンダリングした結果を、dGPU に接続されているディスプレイで表示する場合、dwm が合成する際に PCIe 経由でのデータ転送が発生する(転送のオーバーヘッドがかかる)。

今回のように dGPU の VRAM 負荷を軽減するために iGPU(システムメモリ)にオフロードする場合は、PCIe 転送のオーバーヘッドとのトレードオフがあることに注意が必要。

dGPU の VRAM 負荷を軽減する戦略:

  • アプリ単位でのオフロード
    • GPU 指定機能を使い、軽量なアプリを iGPU に割り当てる
    • dGPU 接続のディスプレイに表示する場合は PCIe 転送のオーバーヘッドが発生
  • マルチディスプレイ構成の活用
    • メインディスプレイを dGPU に接続
    • サブディスプレイを iGPU に接続
      • サブディスプレイ上のアプリを iGPU 指定すれば、転送オーバーヘッドなしでオフロード可能

転送オーバーヘッドは画面領域×更新頻度に比例するため:

  • 大きな画面領域を高頻度で更新するアプリ(フルスクリーンゲーム、動画編集のプレビューなど)は転送コストが大きく、オフロードに不向き
  • 小さい画面や更新頻度が低いアプリ(テキストエディタ、ブラウザの静的ページなど)は転送コストが小さく、オフロードしやすい

具体例:

  • dGPU 優先: 重い3Dゲーム、3DCGレンダリング、大量のテクスチャを使うアプリ、AIモデル推論など
  • iGPU 可: Web ブラウザ、動画再生、コーディング環境、軽量な2Dアプリなど
  1. トップ
  2. tech
  3. iGPU を活用して VRAM の節約

エアコン配管用パテ(白)200g - オーム(OHM)

オーム(OHM)

5.0 / 5.0

外側のエアコンのパテが割れきっていて劣化がひどいので盛りなおした。200gのパテを2つ(400g)使った。

内側も割れてるんだけど、こちらは新しくせず既存のを取り外さずに屋内用の穴うめパテでとりあえず埋めた。

サイネージ HDMI CEC 連携

カレンダーを表示するおうちサイネージ というのを作っていたがモニタの置き場がなくなってしまったので、テレビ画面に映すことにしてみた。

Google TV と Switch でしか使わないので、普段は基本的に Google TV のリモコンで操作している。しかし Raspberry Pi の HDMI を繋いで外部入力をそちらにすると、Google TV のリモコンからの操作 (HDMI CEC信号) をテレビ(SONY BRAVIA)が無視するという困った挙動になった。

試行錯誤してみると Raspberry Pi を HDMI CEC デバイスとして単に参加させる (以下のように)と、他の機器の CEC 信号も無視しなくなるようだった。

# 再生デバイスとして CEC デバイスのネットワークに参加
 cec-ctl --playback

他のデバイスのCEC信号を受けて自動表示

ここまではいいとして、カレンダーアプリはある程度自動的に起動してくれないと見ないため、Google TV のリモコンから電源をオフにすると、自動的に Raspberry Pi のカレンダーを表示する、という挙動にしたくなった。cec-ctl --monitor で HDMI CEC のイベントをストリーム取得できるようなので、これを利用してフックし、他の機器からのSTANDBYがきたら、Raspberry Pi 側に画面を切り替えるという処理を入れた。

 #!/usr/bin/env python3
 import subprocess
 import time
 import re
 import sys
 
 # ====== 設定値 ======
 CEC_ADAPTER_INIT_CMD = ["/usr/bin/cec-ctl", "--playback"]
 CEC_MONITOR_CMD = ["/usr/bin/cec-ctl", "--monitor"]
 TV_ON_CMDS = [
     ["/usr/bin/cec-ctl", "--to", "0", "--image-view-on"],
     ["/usr/bin/cec-ctl", "--to", "0", "--active-source", "phys-addr=4.0.0.0"]
 ]
 DEBUG = True
 # ====================
 
 
 def log(msg):
     """ログ出力(デバッグ時のみ)"""
     if DEBUG:
         print(f"[{time.strftime('%H:%M:%S')}] {msg}", flush=True)
 
 
 def run_cmd(cmd):
     """単発コマンド実行"""
     try:
         subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
         log(f"Executed: {' '.join(cmd)}")
     except subprocess.CalledProcessError as e:
         log(f"Command failed: {cmd} ({e})")
 
 
 def main():
     log("Initializing CEC adapter...")
     run_cmd(CEC_ADAPTER_INIT_CMD)
 
     log("Starting CEC monitor...")
     proc = subprocess.Popen(
         CEC_MONITOR_CMD,
         stdout=subprocess.PIPE,
         stderr=subprocess.STDOUT,
         text=True
     )
 
     last_device_standby = 0
 
     try:
         for line in proc.stdout:
             line = line.strip()
             if not line:
                 continue
 
             # 他のデバイスが STANDBY 送信
             if re.search(r"Received from Playback Device", line) and "STANDBY" in line:
                 log("Detected STANDBY from another playback device")
                 time.sleep(3)
                 for cmd in TV_ON_CMDS:
                     run_cmd(cmd)
 
     except KeyboardInterrupt:
         log("Interrupted by user")
     finally:
         proc.terminate()
         log("Monitor stopped")
 
 
 if __name__ == "__main__":
     if sys.version_info < (3, 6):
         print("Python 3.6+ is required", file=sys.stderr)
         sys.exit(1)
     main()

これを systemd にいれておく

sudo vi /etc/systemd/system/cec-init.service
 [Unit]
 Description=Configure HDMI CEC playback mode
 After=graphical.target
 Wants=graphical.target
 
 [Service]
 Type=oneshot
 ExecStart=/home/pi/cec.py
 RemainAfterExit=true
 
 [Install]
 WantedBy=multi-user.target
 sudo systemctl daemon-reload
 sudo systemctl enable cec-init.service
 sudo systemctl start cec-init.service
 
 sudo systemctl status cec-init.service 
 ● cec-init.service - Configure HDMI CEC playback mode
      Loaded: loaded (/etc/systemd/system/cec-init.service; enabled; preset: enabled)
      Active: activating (start) since Sat 2025-10-18 14:59:08 JST; 11min ago
    Main PID: 2820 (python3)
       Tasks: 2 (limit: 754)
         CPU: 371ms
      CGroup: /system.slice/cec-init.service
              ├─2820 python3 /home/pi/cec.py
              └─2823 /usr/bin/cec-ctl --monitor
 
 Oct 18 14:59:08 sinage systemd[1]: Starting cec-init.service - Configure HDMI CEC playback mode...
 Oct 18 14:59:08 sinage cec.py[2820]: [14:59:08] Initializing CEC adapter...
 Oct 18 14:59:09 sinage cec.py[2820]: [14:59:09] Executed: /usr/bin/cec-ctl --playback
 Oct 18 14:59:09 sinage cec.py[2820]: [14:59:09] Starting CEC monitor...
 Oct 18 15:00:42 sinage cec.py[2820]: [15:00:42] Detected STANDBY from another playback device
 Oct 18 15:00:45 sinage cec.py[2820]: [15:00:45] Executed: /usr/bin/cec-ctl --to 0 --image-view-on
 Oct 18 15:00:45 sinage cec.py[2820]: [15:00:45] Executed: /usr/bin/cec-ctl --to 0 --active-source phys-addr=4.0.0.0
 Oct 18 15:08:43 sinage cec.py[2820]: [15:08:43] Detected STANDBY from another playback device
 Oct 18 15:08:46 sinage cec.py[2820]: [15:08:46] Executed: /usr/bin/cec-ctl --to 0 --image-view-on
 Oct 18 15:08:46 sinage cec.py[2820]: [15:08:46] Executed: /usr/bin/cec-ctl --to 0 --active-source phys-addr=4.0.0.0
  1. トップ
  2. tech
  3. Raspberry Pi から HDMI-CEC コントロール