Управление вентилятором Radeon RX-6xx0: различия между версиями

Материал из ALT Linux Wiki
Строка 106: Строка 106:
#:*частоту опроса температуры '''rate''' со сменой значения в ШИМ-контроллере при необходимости (5 секунд хватает и чтоб не дать перегреться, и чтоб не надоело листать портянку журнала);
#:*частоту опроса температуры '''rate''' со сменой значения в ШИМ-контроллере при необходимости (5 секунд хватает и чтоб не дать перегреться, и чтоб не надоело листать портянку журнала);
#:*температуру '''min_tmp''', ниже которой мослать вентилятором бессмысленно (с завода вентилятор не алё градусов до полусотни минимум, что видно в логе при перезапуске скрипта — см. в [[Управление_вентилятором_Radeon_RX-6xx0#Перезапуск_скрипта_в_жару|примере]] ниже);
#:*температуру '''min_tmp''', ниже которой мослать вентилятором бессмысленно (с завода вентилятор не алё градусов до полусотни минимум, что видно в логе при перезапуске скрипта — см. в [[Управление_вентилятором_Radeon_RX-6xx0#Перезапуск_скрипта_в_жару|примере]] ниже);
#:*шаг '''gap_tmp''' между диапазонами температур (20 градусов);
#:*шаг '''gap_tmp''' между диапазонами температур;
#:*массив '''pwms''' про то, насколько разгоняться — сиречь, какие эмпирически подобранные значения выставлять ШИМу в конкретных температурных диапазонах (и это не об/мин, как можно подумать, а нечто вроде процента от максимума — но не из 100, а из 255).
#:*массив '''pwms''' про то, насколько разгоняться — сиречь, какие эмпирически подобранные значения выставлять ШИМу в конкретных температурных диапазонах (и это не об/мин, как можно подумать, а нечто вроде процента от максимума — но не из 100, а из 255).
#:*'''whithin''' — допустимый разброс значений по границам сверки желаемого значения ШИМ со всегда немного отличающимся от заданного текущим (пытался задействовать ещё для перехлёста температурных диапазонов, дабы вентилятор не дёргался по одному градусу, внося сумятицу в ума и сердца — 1фиг дёргается, и пока не придумал, как победить);
#:*'''whithin''' — допустимый разброс значений по границам сверки желаемого значения ШИМ со всегда немного отличающимся от заданного текущим (пытался задействовать ещё для перехлёста температурных диапазонов, дабы вентилятор не дёргался по одному градусу, внося сумятицу в ума и сердца — 1фиг дёргается, и пока не придумал, как победить);

Версия от 03:02, 26 мая 2022

Введение

Столкнулся с проблемой перегрева видюхи RX-6700XT на игровых нагрузках — и не только её самой, поскольку она ведь и вокруг себя изрядно греет.

  • Процессор прямо над нею кипятится — мéста между видюхой, крышкой и стенками отнюдь не завались.
  • М2-накопитель посреди видюхи и проца тоже знатно подгорает — хоть и с радиатором, и от проц-кулера на него дует... горячим.
  • Дополнительным винчестерам в корзине, вставленной в пространство 5-дюймовых отсеков, жарко и душно.
  • Да и тем, что в нижних 3,5-дюймовых, ни разу не уютно.

До некоторой степени спасает вариант поставить (скорей, положить) перед открытой крышкой системника большой комнатный вентилятор — для всего, кроме самой видюхи: она ж к нему краем, и толку ноль. А заводская авторегулировка видюхиного ШИМа как-то не особо способствует её охлаждению даже зимой, о жаре за бортом вовсе молчу.

Реализация

Пошарив по просторам, нарыл массу графических «мониторилок» — но ни одной «крутилки» именно для АМД, хотя для ненаВидии — завались (один лишь «позеленевший от зависти» чего стóит). И это невзирая на то, что всё нужное доступно прям в системе, без нужды ковыряться в проприетарщине... Странное дело.

Однако наваянного по теме для командной строки хватает на разных языках от рубина до питона, но к чему плодить сущности, если всё можно сделать перманентно доступным башем?

Вдохновлённый этой мыслью, проникся решением amdgpu-fancontrol и выстругал на скорую руку собственный сильно упрощённый вариант, для которого понадобится создать всего пару файлов.

Скрипт запуска

/usr/local/sbin/amdgpufan:

#!/bin/bash
# Check root privileges at first.
[ $UID -eq 0 ] || {
    echo "Writing to /sys requires root privileges."
    exit 1
}

## User variables #############################################
card=0               # Vega rather has number 1
rate=5               # check frequency
min_tmp=40           # no need cooling lower
gap_tmp=$[min_tmp/2] # must not exceed min_tmp
within=$[gap_tmp/2]  # must not exceed gap_tmp
pwms=(70 90 140 210) # pwm values for temperature ranges

## System variables ###########################################
dev_dir=/sys/class/drm/card$card/device
sys_dir=`ls -d $dev_dir/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(){ # Sudden final.
    printf "Exiting and setting fan mode"
    fanmode auto
    exit 0
}

overclock(){ # Just preform.
    echo 8 >$dev_dir/pp_sclk_od # GPU overclockin in percents.
    echo 4 >$dev_dir/pp_mclk_od # Mem overclockin in percents.
}

fanmode(){ # Rule that card or let it on it's own.
    case $1 in
        manual) mode=1;;
        auto)   mode=2;;
        *)      mode=0 # max
    esac
    echo " to '$1'."
    echo $mode >$sys_fan
}

main(){ # Whole magic.
    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 -gt $max_tmp ]]; then
        echo "$cur_tmp°C above critical, setting PWM to $max_pwm for max speed."
        new_pwm=$max_pwm
    elif [[ $cur_tmp -le $min_tmp ]]; then
        new_pwm=$min_pwm
    else
        for i in ${!pwms[@]}; do
            [[ $cur_tmp -ge $[min_tmp+gap_tmp*i]     ]] &&
            [[ $cur_tmp -le $[min_tmp+gap_tmp*(i+1)] ]] && {
                new_pwm=$[min_pwm+${pwms[i]}]
                break
            }
        done
    fi
    printf "%3d°C @%3d PWM" $cur_tmp $cur_pwm
    [[ $cur_pwm -ge $[new_pwm-within] ]] &&
    [[ $cur_pwm -le $[new_pwm+within] ]] &&
    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 # Go on!
    main
    sleep ${rate}s
done

Пояснения

  1. В системных переменных отслеживаю показания датчика самого горячего элемента из трёх — junction (sys_tmp), но в качестве предельной температуры (max_tmp) выбираю минимальную из критических (в моём случае это датчик памяти).
  2. Пользовательскими переменными задаю:
    • № видюхи (судя по статьям от спецов, при наличии встройки оная будет пронумерована единичкой);
    • частоту опроса температуры rate со сменой значения в ШИМ-контроллере при необходимости (5 секунд хватает и чтоб не дать перегреться, и чтоб не надоело листать портянку журнала);
    • температуру min_tmp, ниже которой мослать вентилятором бессмысленно (с завода вентилятор не алё градусов до полусотни минимум, что видно в логе при перезапуске скрипта — см. в примере ниже);
    • шаг gap_tmp между диапазонами температур;
    • массив pwms про то, насколько разгоняться — сиречь, какие эмпирически подобранные значения выставлять ШИМу в конкретных температурных диапазонах (и это не об/мин, как можно подумать, а нечто вроде процента от максимума — но не из 100, а из 255).
    • whithin — допустимый разброс значений по границам сверки желаемого значения ШИМ со всегда немного отличающимся от заданного текущим (пытался задействовать ещё для перехлёста температурных диапазонов, дабы вентилятор не дёргался по одному градусу, внося сумятицу в ума и сердца — 1фиг дёргается, и пока не придумал, как победить);
  3. Сделал скрипт а-ля «резидентным» (цикл while) — запускать по таймеру не стал, дабы между его запусками не оставлять видюху в ручном режиме без управления (см. функцию fanmode).

Запускающий юнит

/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

Как включать юниты, все давно знают. :)

Пример работы

(дату-время и имя-пид процесса убрал для удобочитаемости)

Вечер — веб-сёрфинг, редактирование и пр.

Колебания в пределах 50°C при ШИМ 69.

Запуск игры

 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 при ШИМ 69.

Перезапуск скрипта в жару

По нулевому значению ШИМ на старте видно, что автонастройка не включает вентиляторы как минимум до 50°C:

мая 25 18:01:19 comp.ill amdgpufan[2544596]:  49°C @ 69 PWM.
мая 25 18:01:21 comp.ill systemd[1]: Stopping AMD GPU fan control...
мая 25 18:01:21 comp.ill amdgpufan[2544596]: Завершено
мая 25 18:01:21 comp.ill amdgpufan[2544596]: Exiting and setting fan mode to 'auto'.
мая 25 18:01:21 comp.ill systemd[1]: amdgpufan.service: Deactivated successfully.
мая 25 18:01:21 comp.ill systemd[1]: Stopped AMD GPU fan control.
мая 25 18:01:21 comp.ill systemd[1]: amdgpufan.service: Consumed 1.034s CPU time.
мая 25 18:01:21 comp.ill systemd[1]: Started AMD GPU fan control.
мая 25 18:01:21 comp.ill amdgpufan[2558019]: Wrong fan mode, setting to 'manual'.
мая 25 18:01:21 comp.ill amdgpufan[2558019]:  49°C @  0 PWM, changing to  70.
мая 25 18:01:26 comp.ill amdgpufan[2558019]:  49°C @ 69 PWM.

Игра по жаре

 92°C @ 87 PWM, changing to 140.

Далее колебания на 90+°C при ШИМ 138.

Выводы

На данный момент ночью, по прохладе, большой внешний вентилятор уже точно не нужен: игрушки на ультрах в высоком разрешении прогревают самый горячий компонент видюхи не выше 96 градусов, тогда как прежде и с вентилятором за сотку вылезало. Вечером в пределах +30 на улице тоже обошёлся без вентилятора. Как оно в дневную жару, опробовать пока не довелось, но по результатам отчитаюсь.

Когда не ломанная / не чиненная железяка работает не так, как ожидается, порой на помощь спешат чип и... программные средства. Пусть без рюшечек и фантиков, зато задача решена на системном уровне. Ну, и есть надежда, что дружелюбного софта тоже не придётся долго ждать.

Послесловие

А ведь есть ещё варианты разгона с понижением напруги типа такого. С учётом побеждённого перегрева, отчего б и его не задействовать... :)

Обратная связь

@gbIMoBou

Другие статьи