2022-12-22

AMDGPU の PowerPlay で省電力化できた

なぜもっと早くに手を付けなかったんだと後悔しましたが、無事に省電力化で来たのでまあ良しとします。

きっかけは AMD P-State Driver の有効化で CPU の温度が下がったことです。今は冬で室温が低いということもありますが、CPU 温度が 33.6度に対して GPU 温度は 48度を示しています。「艦これ」をプレイ中は 50度を超え、54度くらいまで上昇します。


GPU は Radeon RX 570 を使っているのですが、コイツも動作クロックを意図的に落とせれば省電力化できるのではないかと考えました。「ん〜、そう言えば前にそんな記事を見た気もする」ということで掘り起こせたのがこちらの記事です。

Linux環境で AMDGPU のクロック、電圧を調節 ―― OC/UV

2020年 11月に投稿された記事なのに、なんで今まで手を付けなかったんだろう?不思議です。

 

記事中には「/sys/class/drm/card0/device 配下に pp_od_clk_voltage というファイルがあり、ここに設定可能なクロックの一覧がある」という記載があるのですが、ワタシの環境にはこのファイル自体が存在していませんでした。

/sys/class/drm/card0/device
$ ls
aer_dev_correctable        hwmon                    msi_bus                            rescan
aer_dev_fatal              i2c-0                    msi_irqs                           reset
aer_dev_nonfatal           i2c-1                    numa_node                          reset_method
ari_enabled                i2c-2                    pcie_bw                            resource
boot_vga                   iommu                    pcie_replay_count                  resource0
broken_parity_status       iommu_group              power                              resource0_wc
class                      irq                      power_dpm_force_performance_level  resource2
config                     link                     power_dpm_state                    resource2_wc
consistent_dma_mask_bits   local_cpulist            power_state                        resource4
consumer:pci:0000:06:00.1  local_cpus               pp_cur_state                       resource5
current_link_speed         max_link_speed           pp_dpm_mclk                        revision
current_link_width         max_link_width           pp_dpm_pcie                        rom
d3cold_allowed             mem_busy_percent         pp_dpm_sclk                        serial_number
device                     mem_info_gtt_total       pp_force_state                     subsystem
dma_mask_bits              mem_info_gtt_used        pp_mclk_od                         subsystem_device
driver                     mem_info_preempt_used    pp_num_states                      subsystem_vendor
driver_override            mem_info_vis_vram_total  pp_power_profile_mode              thermal_throttling_logging
drm                        mem_info_vis_vram_used   pp_sclk_od                         uevent
enable                     mem_info_vram_total      pp_table                           vbios_version
fw_version                 mem_info_vram_used       product_name                       vendor
gpu_busy_percent           mem_info_vram_vendor     product_number
graphics                   modalias                 remove

どうやら当時のワタシはこれで諦めてしまったんだと思います。若いってスバラシイ!

 

ところが、今日のワタシにはそんなことは関係ありませんでした。猪突猛進です。

PowerPlay を有効化するには、まずは kernel 起動オプションを変更する必要があります。先日に AMD P-State Driver の有効化のために kernel 起動オプションを変更しまくっているので全く怖いものはありませんでした。

するとどうでしょう。さっきまでは存在していなかった例のファイルがひょっこり登場しました。なるほどね。

/sys/class/drm/card0/device
$ ls
aer_dev_correctable        hwmon                    msi_bus                            remove
aer_dev_fatal              i2c-0                    msi_irqs                           rescan
aer_dev_nonfatal           i2c-1                    numa_node                          reset
ari_enabled                i2c-2                    pcie_bw                            reset_method
boot_vga                   iommu                    pcie_replay_count                  resource
broken_parity_status       iommu_group              power                              resource0
class                      irq                      power_dpm_force_performance_level  resource0_wc
config                     link                     power_dpm_state                    resource2
consistent_dma_mask_bits   local_cpulist            power_state                        resource2_wc
consumer:pci:0000:06:00.1  local_cpus               pp_cur_state                       resource4
current_link_speed         max_link_speed           pp_dpm_mclk                        resource5
current_link_width         max_link_width           pp_dpm_pcie                        revision
d3cold_allowed             mem_busy_percent         pp_dpm_sclk                        rom
device                     mem_info_gtt_total       pp_force_state                     serial_number
dma_mask_bits              mem_info_gtt_used        pp_mclk_od                         subsystem
driver                     mem_info_preempt_used    pp_num_states                      subsystem_device
driver_override            mem_info_vis_vram_total  pp_od_clk_voltage                  subsystem_vendor
drm                        mem_info_vis_vram_used   pp_power_profile_mode              thermal_throttling_logging
enable                     mem_info_vram_total      pp_sclk_od                         uevent
fw_version                 mem_info_vram_used       pp_table                           vbios_version
gpu_busy_percent           mem_info_vram_vendor     product_name                       vendor
graphics                   modalias                 product_number

ちなみに待ち望んでいた pp_od_clk_voltage の中身は以下の通りでした。

/sys/class/drm/card0/device
$ cat pp_od_clk_voltage 
OD_SCLK:
0:        300MHz        750mV
1:        588MHz        765mV
2:        952MHz        931mV
3:       1041MHz       1006mV
4:       1106MHz       1068mV
5:       1168MHz       1131mV
6:       1209MHz       1150mV
7:       1244MHz       1150mV
OD_MCLK:
0:        300MHz        750mV
1:       1000MHz        800mV
2:       1500MHz        900mV
OD_RANGE:
SCLK:     300MHz       2000MHz
MCLK:     300MHz       2250MHz
VDDC:     750mV        1150mV

SCLK が GPU のプロセッサークロックで、MCLK が GPU のメモリークロックのようです。GPU の温度を下げたいので SCLK をあまり高い値まで使わないように制限できると良さそうです。

Radeon RX 570 のスペックシートを見てみると、コアクロックが 1168MHz、ブースト時が 1244MHz とのことです。上限を制限するとしたら、1041MHz とか 952MHz あたりでしょうか。

設定方法をもう少し調べていたところ、お手軽な省電力モードというものが用意されていることを発見しました。まずはこれでどんな感じか試してみよう、というわけです。

 

で、調べものをするといつものように ArchWiki に辿り着くというのはこの世の七不思議なのではいかと思っています。

AMDGPU - ArchWiki

 

なんでも「電源プロファイル」の No.2 に「POWER_SAVING」というモードが用意されているようなので、これを設定してみるといいようです。

まずは kernel 起動オプションを変更して PC を再起動させます。マスク値に 0xffffffff を指定する例もありましたが、慎重に 0xfff7ffff で試してみました。

$ cat /etc/default/grub
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
#   info -f grub -n 'Simple configuration'

GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT amd_pstate.shared_mem=1"
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT amdgpu.ppfeaturemask=0xfff7ffff"
GRUB_CMDLINE_LINUX=""

続いて、PowerPlay のマニュアルモードへの移行を宣言します。

$ sudo sh -c "echo "manual" > /sys/class/drm/card0/device/power_dpm_force_performance_level"

そして、POWER_SAVING モードに設定変更します。(これでもう反映されます)

$ sudo sh -c "echo "2" > /sys/class/drm/card0/device/pp_power_profile_mode"

設定変更前の状態です。

$ sudo cat /sys/kernel/debug/dri/0/amdgpu_pm_info
GFX Clocks and Power:
	300 MHz (MCLK)
	871 MHz (SCLK)
	588 MHz (PSTATE_SCLK)
	1000 MHz (PSTATE_MCLK)
	931 mV (VDDGFX)
	15.19 W (average GPU)

GPU Temperature: 40 C
GPU Load: 0 %
MEM Load: 1 %

UVD: Disabled

VCE: Disabled

設定変更後の状態です。

$ sudo cat /sys/kernel/debug/dri/0/amdgpu_pm_info
GFX Clocks and Power:
	300 MHz (MCLK)
	300 MHz (SCLK)
	588 MHz (PSTATE_SCLK)
	1000 MHz (PSTATE_MCLK)
	750 mV (VDDGFX)
	8.202 W (average GPU)

GPU Temperature: 37 C
GPU Load: 2 %
MEM Load: 1 %

UVD: Disabled

VCE: Disabled

ん〜、パッと見でそんなに違いはないですね。average GPU は 15W から 8Wに下がってますね。VDDGFX も 750mV に下がってます。あとは SCLK が 871MHz から 300MHz に下がってますね。GPU 温度も 40度から 37度に下がってますね。

むしろ UVD、VCE が「無効」と表示されている方が気になります。

 

それはさておき、このまましばらく使ってみた状態がこちらのスクリーンショットです。

わが家で最も GPU に負荷をかける「艦これ」をプレイ中に、なんと YouTube の再生までさせちゃいました。これで GPU 温度は 40度前後なので設定変更前に比べると 10度〜14度ほど下がっています。

いやぁ、何度も言いますがどうして今まで手を付けなかったんでしょう。悔やまれます。

 

ところで、AMD P-State Driver も PowerPlay も PC を再起動すると設定値が元に戻ってしまいます。ワタシは普段はサスペンド運用なので PC を再起動することがそんなに多くないのですが、シェルスクリプトにでもまとめておこうかと思います。

(おまけ)
AMDGPU driver のドキュメントはこちらを参照。例えば、power_dpm_force_performance_level に設定できる値の説明があったりします。

GPU Driver Documentation 5.15