Управление вентилятором Radeon RX-6xx0
Введение
Столкнулся с проблемой перегрева видюхи RX-6700XT на игровых нагрузках — и не только её самой, поскольку она ведь и вокруг себя знатно греет.
- Процессор прямо над нею кипятится — места в простенке между видюхой, крышкой и стенками отнюдь не завались.
- М2-накопитель между видюхой и процом тоже знатно подгорает, хоть и с радиатором, и от проц-кулера на него дует... горячим. :)
- Дополнительные винчестеры в корзине, вставленной в пространство 5-дюймовых отсеков.
- Да и тем, что в нижних 3,5-дюймовых отсеках, ни разу не уютно.
В некоторой степени спасает вариант поставить (скорей, положить) перед открытой крышкой системника большой комнатный вентилятор — для всего, кроме самой видюхи: она ж к нему торцом. А заводская авторегулировка видюхиного ШИМа как-то не особо способствует её охлаждению даже зимой, о жаре за бортом вовсе молчу.
Реализация
Вдохновлённый решением одного немца amdgpu-fancontrol
, сваял собственный сильно упрощённый вариант.
Понадобится создать пару файлов.
Скрипт запуска
/usr/local/sbin/amdgpufan
:
#!/bin/bash
# Check root privileges first.
[ $UID -eq 0 ] || {
echo "Writing to /sys requires root privileges."
exit 1
}
## User variables #############################################
card=0
rate=5
min_tmp=40
gap_tmp=$[min_tmp/2]
## System variables ###########################################
sys_dir=`ls -d /sys/class/drm/card$card/device/hwmon/*`
## temp# - 1:edge, 2:junction, 3:memory
sys_tmp=${sys_dir}/temp2_input
sys_pwm=${sys_dir}/pwm1
sys_fan=${sys_pwm}_enable
min_pwm=`cat ${sys_pwm}_min`
max_pwm=`cat ${sys_pwm}_max`
max_tmp=$[`cat ${sys_dir}/temp*_crit | sort -V | head -1`/1000]
###############################################################
reset(){
printf "Exiting and setting fan mode"
fanmode auto
exit 0
}
fanmode(){
case $1 in
manual) mode=1;;
auto) mode=2;;
*) mode=0 # max
esac
echo " to '$1'."
echo $mode >$sys_fan
}
main(){
cur_pwm=`cat $sys_pwm`
cur_tmp=$[`cat $sys_tmp`/1000]
[[ `cat $sys_fan` -eq 1 ]] || {
printf "Wrong fan mode, setting"
fanmode manual
}
if [[ $cur_tmp -ge $max_tmp ]]; then
echo "$cur_tmp°C above critical, setting PWM to $max_pwm for max speed."
new_pwm=$max_pwm
else
[[ $cur_tmp -le $min_tmp ]] && new_pwm=$min_pwm || {
for n in `seq 0 3`; do
case $n in
0) add=70;;
1) add=90;;
2) add=140;;
3) add=210;;
esac
[[ $cur_tmp -ge $[min_tmp+gap_tmp*n] ]] &&
[[ $cur_tmp -le $[min_tmp+gap_tmp*(n+1)] ]] && {
new_pwm=$[min_pwm+add]
break
}
done
}
fi
printf "%3d°C @%3d PWM" $cur_tmp $cur_pwm
[[ $cur_pwm -ge $[new_pwm-2] ]] &&
[[ $cur_pwm -le $new_pwm ]] &&
echo "." || { # Change PWM if differ.
printf ", changing to %3d.\n" $new_pwm
echo $new_pwm >$sys_pwm
}
}
trap "reset" SIGINT SIGTERM # Handle signals.
while :; do # run daemon
main
sleep ${rate}s
done
Пояснения
- В системных переменных отслеживаю (sys_tmp) показания датчика самого горячего элемента из трёх —
junction
, но в качестве предельной температуры (max_tmp) выбираю минимальную из критических (в моём случае это датчик памяти). - Пользовательскими переменными задаю:
- № видюхи (если есть встройка, она, вероятно, будет пронумерована единичкой);
- частоту опроса температуры со сменой состояния ШИМ-контроллера при необходимости (5 секунд хватает и чтоб не дать перегреться, и чтоб не надоело листать портянку журнала);
- температуру, ниже которой мослать вентилятором бессмысленно (с завода вентилятор начинает слегка шевелиться вообще градусов с полусотни);
- шаг между диапазонами температур (20 градусов).
- В выборке case цикла for указываю, насколько разгоняться — сиречь, какие значения выставлять ШИМ-контроллеру в этих температурных диапазонах. Задаваются не об/мин, как можно подумать, а нечто вроде процента от максимума — но не из 100, а из 255.
Запускающий юнит
/lib/systemd/system/amdgpufan.service
:
[Unit]
Description = AMD GPU fan control
[Service]
ExecStart = /usr/local/sbin/amdgpufan
Restart = on-failure
RestartSec = 5
[Install]
WantedBy = default.target
Пример работы
(дату-время и имя-пид процесса убрал для удобочитаемости):
Вечер: веб-сёрфинг, редактирование и пр. Колебания Т°C при PWM 69 54°C @ 69 PWM. ...Запуск игры. 60°C @ 69 PWM, changing to 90. 59°C @ 89 PWM, changing to 70. 60°C @ 69 PWM, changing to 90. 57°C @ 89 PWM, changing to 70. 54°C @ 69 PWM. 59°C @ 69 PWM. 62°C @ 69 PWM, changing to 90. 77°C @ 89 PWM. ...Активная фаза игры. 82°C @ 89 PWM, changing to 140. 62°C @138 PWM, changing to 90. 59°C @ 89 PWM, changing to 70. 62°C @ 69 PWM, changing to 90. 60°C @ 89 PWM. ... 61°C @ 89 PWM. 62°C @ 89 PWM. 58°C @ 89 PWM, changing to 70. 60°C @ 69 PWM, changing to 90. 75°C @ 89 PWM. ...Игра завершена, плавное падение температуры. 53°C @ 89 PWM, changing to 70. 52°C @ 69 PWM. 40°C @ 69 PWM. 39°C @ 69 PWM, changing to 0. 40°C @ 0 PWM, changing to 70. 39°C @ 69 PWM, changing to 0. 39°C @ 0 PWM. ...Ночь: колебания 35-38°C с отключёнными вентиляторами видюхи. ...Утро: вход в систему, веб-сёрфинг, редактирование и пр. 40°C @ 0 PWM, changing to 70. 41°C @ 69 PWM. ...Колебания 42-55°C
Выводы
Когда не ломанная / не чиненная железяка работает не так, как ожидается, порой на помощь спешат чип и... программные средства. Пусть без рюшечек и фантиков, зато задача решена на системном уровне. Ну, и есть надежда, что дружелюбного софта тоже не придётся долго ждать.
Послесловие
А ведь есть ещё варианты разгона с понижением вольтажа типа такого. С учётом побеждённого перегрева, отчего б и его не задействовать... :)