본문 바로가기

Linux

리눅스에서 Radeon GPU 클럭, 전압 조정하기

앞으로 티스토리 대신 blog.stackframe.dev에서 블로깅을 합니다. 이 블로그는 남겨 둘 예정입니다.

AMD의 Radeon 그래픽카드를 산다면 언제나 전압이나 클럭을 조정해줘야 제대로된 퍼포먼스가 나온다는 설이 있습니다. 실제로 제품의 전압 마진이 어느정도 있기 때문에 오버클럭으로 성능을 높히거나 언더볼팅으로 전력 소비를 줄일 수 있습니다.

 

윈도우즈에는 AMD가 라데온 드라이버와 함께 Wattman을 제공하기 때문에 손쉽게 클럭과 전압을 조정할 수 있습니다. 다만 리눅스에서는 그런 툴을 제공하지 않기 때문에 직접 터미널에서 명령을 내려야합니다.

 

먼저 클럭과 전압을 조정하기 위한 조건은 리눅스 커널이 4.20은 되어야합니다. 그리고 부팅할 때 커널 파라메터로 amdgpu.ppfeaturemask=0xffffffff 가 포함되어야 합니다. 커널 파라메터를 설정하는 것은 사용하는 부트로더에 따라 다릅니다. 일반적으로 사용하는 GRUB 이라면 /etc/default/grub 파일의 GRUB_CMDLINE_LINUX_DEFAULT 변수 안에 추가하고 update-grub 명령을 실행하시면 됩니다.

저는 systemd-boot를 사용하기 때문에 /boot/loader/entries/ 안의 엔트리 파일의options에 추가했습니다.

또 저는 RX570을 사용하고 있고, Polaris 아키텍처 이전의 장치에 대해서는 이 기능이 사용가능한지 모릅니다. 그리고 Vega20은 전압 조정하는 방법이 조금 다르므로 여기서는 다루지 않겠습니다.

 

커널 파라메터를 제대로 설정하고 부팅하였다면 /sys/class/drm/card0/device/ 디렉토리 안에 pp_od_clk_voltage 등의 파일이 추가되었을 것입니다.

저희가 원하는 것은 클럭과 전압 조정이므로 먼저 수동으로 설정할 수 있게 변경합니다.

# echo 'manual' > /sys/class/drm/card0/device/power_dpm_force_performance_level

사실 이거 안해주고도 아래의 명령을 실행하면 적용되던데 amdgpu 커널 드라이버 코드 주석을 보면 해주라고 되어있기에 순순히 따라줍시다.

저 디렉토리에 표시된 여러 파일들에 대해 궁금하신 분은 https://kernel.org 에서 리눅스 커널 소스코드를 다운받고 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c 의 주석을 읽어보시면 도움이 됩니다.

 

이번엔 pp_od_clk_voltage 파일을 읽어봅시다.

$ cat /sys/class/drm/card0/device/pp_od_clk_voltage

cat으로 출력해보면 위와같이 표시됩니다.

몇몇 알고가야할 용어가 있는데 SLCK는 GPU클럭을 의미하고, MLCK는 GPU의 VRAM 클럭을 의미합니다.

여기서 중요하게 봐야할 것은 맨 마지막의 OD_RANGE입니다. 이것은 설정할 수 있는 최소, 최대 클럭과 전압을 보여줍니다.

저는 GPU 클럭은 최소 300MHz에 최대 2000MHz, 메모리클럭은 300MHz에서 2250MHz, 전압은 750mV에서 1150mV까지 설정할 수 있다고 나옵니다.

물론 설정할 수 있다고해서 그 클럭으로 정상작동한다는 것은 보장하지 않습니다. 너무 과한 클럭과 전압을 준다면 GPU가 죽어버리는 경우도 생깁니다.

그리고 OD_SCLK, OD_MCLK 부분은 P states라고 해서 현재 GPU 사용률에 따라 어느정도의 클럭에 어느정도의 전압을 사용할건지 나타내는 테이블입니다.

 

최소, 최대 범위를 알았으면 클럭과 전압을 설정할 시간입니다.

클럭과 전압을 설정하는 방법은 pp_od_clk_voltage 파일에 특정 값의 문자열을 쓰기를 하는 것입니다. 리눅스의 재미있는 특성으로 모든 것을 파일로 취급하기 때문에 이런 인터페이스마저 파일로 처리가 가능한겁니다.

 

그 문자열은 아래와 같은 포맷입니다.

<s/m> <state 번호> <클럭> <전압>

맨 첫 번째의 값은 GPU state를 변경하려면 s를, GPU 메모리의 state를 변경하려면 m을 입력합니다.

두 번째는 변경할 state 번호를 입력합니다. SLCK는 0 ~ 7, MLCK는 0 ~ 2 까지의 범위인 것을 위에서 보았으니 넘어가지 않게 입력합시다.

세 번째는 클럭을 입력합니다.

네 번째는 전압을 입력합니다.

 

사실 제가 아무리봐도 이렇게 설명하는 것보다 예시 하나 보여주는게 가장 쉽게 이해가 되는 것 같습니다.

예시로 SLCK의 마지막 state인 7에 1200MHz 클럭에다가 1040mV를 적용한다면 아래와 같습니다.

s 7 1200 1040

이 문자열을 pp_od_clk_voltage에 쓰기 위해서는 터미널에서 아래와 같이 실행합니다.

# echo 's 7 1200 1040' > /sys/class/drm/card0/device/pp_od_clk_voltage

사진을 보면 7번 state가 설정한 값대로 바뀐 것을 볼 수 있습니다.

하지만 이것으로는 아직 설정이 적용되지 않았습니다. AMD에서 꼭 다시 한번 설정한 값을 확인하라는 취지에서인지 'c' 문자를 쓰기해야만 비로소 설정이 적용되도록 만들어져 있습니다.

# echo 'c' > /sys/class/drm/card0/device/pp_od_clk_voltage

이렇게 하면 리눅스에서 GPU의 클럭과 전압을 설정할 수 있습니다. 추가적으로 원상태로 되돌리고 싶다면 'r' 문자를 쓰기하면 테이블을 기본 설정으로 되돌립니다. 이것도 물론 'c'를 쓰기 해야만 기본 설정이 적용됩니다.

 

클럭을 조정하다가 늘 만나는 것이 바로 저전압 상태인데 화면이 냉납현상에 걸린 것처럼 모자이크가 생기거나 다수의 줄이 생깁니다. 그럴경우 침착하게 컴퓨터를 재부팅하면 됩니다. 위의 설정은 컴퓨터를 끄면 유지되지 않습니다. 그러므로 재부팅 이후에도 유지하고 싶다면 쉘 스크립트를 만들어서 systemd에 등록하면 됩니다.

 

저는 무슨 영문인지 SLCK의 7번 클럭을 조정하고 기본 설정으로 되돌리니 저전압에 걸린 것처럼 화면이 깨집니다... 이론적으로 생각해봐도 원래 잘 작동하던 클럭인데 조정했다가 되돌리면 문제가 생기니 왜 그런건지 모르겠습니다.