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

Материал из ALT Linux Wiki
 
(не показано 118 промежуточных версий этого же участника)
Строка 1: Строка 1:
[[Файл:1.Zalman Z1.jpg|мини|Zalman Z1]]
=Введение=
=Введение=
Столкнулся с проблемой перегрева видюхи RX-6700XT на игровых нагрузках — и не только её самой, поскольку она ведь и вокруг себя изрядно греет.
Столкнулся с проблемой перегрева видюхи RX-6700XT на игровых нагрузках — и не только её самой, поскольку она ведь и вокруг себя изрядно греет.
*Процессор прямо над нею кипятится — мéста между видюхой, крышкой и стенками отнюдь не завались.
*Процессор прямо над нею кипятится — мéста между видюхой, крышкой и стенками отнюдь не завались.
*М2-накопитель посреди видюхи и проца тоже знатно подгорает — хоть и с радиатором, и от проц-кулера на него дует... горячим.
*М2-накопитель посреди видюхи и проца тоже знатно подгорает — хоть и с радиатором, и от проц-кулера на него дует… горячим.
*Дополнительным винчестерам в корзине, вставленной в пространство 5-дюймовых отсеков, жарко и душно.
*Дополнительным винчестерам в корзине, вставленной в пространство 5-дюймовых отсеков, жарко и душно.
*Да и тем, что в нижних 3,5-дюймовых, ни разу не уютно.
*Да и тем, что в нижних 3,5-дюймовых, ни разу не уютно.
До некоторой степени спасает вариант поставить (скорей, положить) перед открытой крышкой системника большой комнатный вентилятор — для всего, кроме самой видюхи: она ж к нему краем, и толку ноль. А заводская авторегулировка видюхиного ШИМа как-то не особо способствует её охлаждению даже зимой, о жаре за бортом вовсе молчу.
До некоторой степени спасает вариант поставить перед открытой крышкой системника большой настольный вентилятор (см. фото) — для всего, кроме самой видюхи: она ж к нему краем, и толку почти ноль. А заводская авторегулировка видюхиного ШИМа как-то не особо способствует её охлаждению даже зимой, о жаре за бортом вовсе молчу.
=Реализация=
[[Файл:4.Final.jpg|мини|AeroCool xPredator FullTower]]
Пошарив по просторам, нарыл массу графических «мониторилок» — но ни одной «крутилки» именно для АМД, хотя для ненаВидии — завались (один лишь [https://www.flathub.org/apps/details/com.leinardi.gwe «позеленевший от зависти»] чего стóит). И это невзирая на то, что всё нужное доступно прямо из системы, без нужды ковыряться в проприетарщине… Странное дело.
 
При этом для командной строки нарубинено да напитонено всякого, но к чему плодить сущности, если всё можно сделать перманентно доступным шеллом? Проникся довольно замороченным решением [https://github.com/WieWaldi/amdgpu-fancontrol <code>amdgpu-fancontrol</code>] и по образу/подобию слепил на скорую руку собственный упрощённый вариант, для которого понадобится тройка файлов — скрипт да конфиг c юнитом к нему (выложены на [https://github.com/Smoque/amdgpufan ГитХаб]).
===1) Файл настроек===
{|class="mw-collapsible mw-collapsed wikitable"
!/etc/sysconfig/amdgpufan &nbsp;
|-
|<source lang="ini">
# restart service amdgpufan if config changed
card=0          # vega rather has number 1
rate=3          # check frequency
step=5          # min to max divider
within=2        # temperature borders and pwm diff tolerance
min_tmp=45      # no need cooling lower
sensor=junction # 'edge' (gpu), 'mem' or 'junction' (hottest one)
</source>
|}
===2) Запускающий юнит===
{|class="mw-collapsible mw-collapsed wikitable"
!/lib/systemd/system/amdgpufan.service &nbsp;
|-
|<source lang="ini">
[Unit]
Description = AMD GPU fan control


=Реализация=
[Service]
Пошарив по просторам, нарыл массу графических «мониторилок» — но ни одной «крутилки» именно для АМД, хотя для ненаВидии — завались (один лишь [https://www.flathub.org/apps/details/com.leinardi.gwe «позеленевший от зависти»] чего стóит). И это невзирая на то, что всё нужное доступно прям в системе, без нужды ковыряться в проприетарщине... Странное дело.
ExecStart = /usr/local/sbin/amdgpufan
Restart = on-failure
RestartSec = 5


Однако наваянного по теме для командной строки хватает на разных языках от рубина до питона, но к чему плодить сущности, если всё можно сделать перманентно доступным башем?
[Install]
WantedBy = default.target
</source>
|}
Как включать юниты, все давно знают. :)
===3) Сам скрипт===
{|class="mw-collapsible mw-collapsed wikitable"
!/usr/local/sbin/amdgpufan &nbsp;
|-
|<source lang="bash">
#!/bin/sh


Вдохновлённый этой мыслью, проникся решением [https://github.com/WieWaldi/amdgpu-fancontrol <code>amdgpu-fancontrol</code>] и выстругал на скорую руку собственный сильно упрощённый вариант, для которого понадобится создать всего пару файлов.
[ $UID -eq 0 ] || { # Check user permissions.
==Скрипт запуска==
<code>/usr/local/sbin/amdgpufan</code>:
<source lang="bash">
#!/bin/bash
# Check root privileges at first.
[ $UID -eq 0 ] || {
     echo "Writing to /sys requires root privileges."
     echo "Writing to /sys requires root privileges."
     exit 1
     exit 1
}
}


## User variables #############################################
## User defaults if config absend ################################
card=0               # Vega rather has number 1
card=0         # vega rather has number 1
rate=5              # check frequency
rate=3          # check frequency
min_tmp=40          # no need cooling lower
step=5          # min to max divider
gap_tmp=$[min_tmp/2] # must not exceed min_tmp
within=2       # temperature borders and pwm diff tolerance
within=$[gap_tmp/2]  # must not exceed gap_tmp
min_tmp=45      # no need cooling lower
pwms=(70 90 140 210) # pwm values for temperature ranges
sensor=junction # 'edge' (gpu), 'mem' or 'junction' (hottest one)


## System variables ###########################################
config=/etc/sysconfig/amdgpufan
[ -f $config -a -s $config ] && source $config ||
echo "User settings not found, using default values."
 
case $sensor in
    junction) # let's add some degrees to most hot sensor
        let min_tmp+=5
        sensor=2;;
    edge)sensor=1;;
    mem) sensor=3;;
esac
 
## System variables ##############################################
gpuinfo=/sys/kernel/debug/dri/$card/amdgpu_pm_info
dev_dir=/sys/class/drm/card$card/device
dev_dir=/sys/class/drm/card$card/device
sys_dir=`ls -d $dev_dir/hwmon/*`
sys_dir=`ls -d $dev_dir/hwmon/*`
## temp# - 1:edge, 2:junction, 3:memory
sys_lvl=${dev_dir}/power_dpm_force_performance_level
sys_tmp=${sys_dir}/temp2_input
sys_clk=${dev_dir}/pp_od_clk_voltage
sys_tmp=${sys_dir}/temp${sensor}_input
sys_pwm=${sys_dir}/pwm1
sys_pwm=${sys_dir}/pwm1
sys_fan=${sys_pwm}_enable
sys_fan=${sys_pwm}_enable
## Calculated variables ##########################################
part=$[step-2] # loops' divider: steps num except first and last
# Achievable frequencies for gpu & mem:
mhz=(`awk '/^(M|S)/{gsub("Mhz","");print $3}' $sys_clk | sort -V`)
max_tmp=$[`cat $sys_dir/temp*_crit | sort -V | head -1`/1000]
max_pwm=`cat ${sys_pwm}_max`
min_pwm=`cat ${sys_pwm}_min`
min_pwm=`cat ${sys_pwm}_min`
max_pwm=`cat ${sys_pwm}_max`
gap_pwm=$[(max_pwm-min_pwm)/step]
max_tmp=$[`cat $sys_dir/temp*_crit | sort -V | head -1`/1000]
gap_tmp=$[(max_tmp-min_tmp)/step]


reset(){ # Sudden final.
reset(){ # Sudden break.
     printf "Exiting and setting fan mode"
     printf "Exiting and s"
     fanmode auto
     setmode auto
     exit 0
     exit 0
}
}


overclock(){ # Just preform.
setmode(){ # Change as mode as gpu & mem frequency.
     echo 8 >$dev_dir/pp_sclk_od # GPU overclockin in percents.
     echo "etting clock & fan mode to '$1'."
    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
     case $1 in
        manual) mode=1;;
         auto)  mode=2;;
         auto)  mode=2;;
         *)     mode=0 # max
         manual) mode=1
                echo m 1 ${mhz[0]}  >$sys_clk
                echo s 1 ${mhz[1]}  >$sys_clk
        ;;
     esac
     esac
     echo " to '$1'."
     echo $mode  >$sys_fan
     echo $mode >$sys_fan
     echo $1    >$sys_lvl
}
}


Строка 67: Строка 119:
     cur_tmp=$[`cat $sys_tmp`/1000]
     cur_tmp=$[`cat $sys_tmp`/1000]
     [[ `cat $sys_fan` -eq 1 ]] || {
     [[ `cat $sys_fan` -eq 1 ]] || {
         printf "Wrong fan mode, setting"
         printf "S"
         fanmode manual
         setmode manual
     }
     }
     if [[ $cur_tmp -gt $max_tmp ]]; then
     if [[ $cur_tmp -gt $max_tmp ]]; then
         echo "$cur_tmp°C above critical, setting PWM to $max_pwm for max speed."
         echo "$cur_tmp°C exceeds critical, set 100% blowing."
         new_pwm=$max_pwm
         new_pwm=$max_pwm
     elif [[ $cur_tmp -le $min_tmp ]]; then
     elif [[ $cur_tmp -le $min_tmp ]]; then
         new_pwm=$min_pwm
         new_pwm=$min_pwm
     else
     else
         for i in ${!pwms[@]}; do
         for i in `seq 0 $part`; do
             [[ $cur_tmp -ge $[min_tmp+gap_tmp*i]    ]] &&
             [[ $cur_tmp -ge $[min_tmp+gap_tmp*i]    ]] &&
             [[ $cur_tmp -le $[min_tmp+gap_tmp*(i+1)] ]] && {
             [[ $cur_tmp -le $[min_tmp+gap_tmp*(i+1)] ]] && {
                 new_pwm=$[min_pwm+${pwms[i]}]
                 new_pwm=$[min_pwm+gap_pwm*(i+1)]
                 break
                 break
             }
             }
Строка 87: Строка 139:
     [[ $cur_pwm -ge $[new_pwm-within] ]] &&
     [[ $cur_pwm -ge $[new_pwm-within] ]] &&
     [[ $cur_pwm -le $[new_pwm+within] ]] &&
     [[ $cur_pwm -le $[new_pwm+within] ]] &&
     echo "." || { ## Change PWM if differ.
     echo "." || { # Change PWM if differ.
         printf ", changing to %3d.\n" $new_pwm
         for i in `seq 0 $part`; do
        echo $new_pwm >$sys_pwm
            [[ $cur_tmp -ge $[min_tmp+gap_tmp*i-within] ]] &&
            [[ $cur_tmp -le $[min_tmp+gap_tmp*i+within] ]] && {
                echo "."
                break
            }
        done || {
            printf ", switching to %3d.\n" $new_pwm
            echo $new_pwm >$sys_pwm
        }
     }
     }
}
}
Строка 100: Строка 160:
done
done
</source>
</source>
|}
===Пояснения===
===Пояснения===
#В системных переменных отслеживаю показания датчика самого горячего элемента из трёх — <code>junction</code> ('''sys_tmp'''), но в качестве предельной температуры ('''max_tmp''') выбираю минимальную из критических (в моём случае это датчик памяти).
#Пользовательскими переменными из конфига задаю:
#Пользовательскими переменными задаю:
#:*'''card''' — № видюхи (судя по статьям от спецов, при наличии встройки оная будет пронумерована единичкой);
#:*№ видюхи (судя по статьям от спецов, при наличии встройки оная будет пронумерована единичкой);
#:*'''min_tmp''' температуру, ниже которой мослать вентилятором бессмысленно (с завода вентилятор не включается до 52°C процессора, а при остывании останавливается на 46°C);
#:*частоту опроса температуры '''rate''' со сменой значения в ШИМ-контроллере при необходимости (5 секунд хватает и чтоб не дать перегреться, и чтоб не надоело листать портянку журнала);
#:*'''sensor''' — какой из датчиков «пасти»: процессора, самый холодный (памяти) или самый горячий (температуры перехода), однако '''max_tmp''' выбираю минимальную из критических;
#:*температуру '''min_tmp''', ниже которой мослать вентилятором бессмысленно (с завода вентилятор не алё градусов до полусотни минимум, что видно в логе при перезапуске скрипта — см. в [[Управление_вентилятором_Radeon_RX-6xx0#Перезапуск_скрипта_в_жару|примере]] ниже);
#:*'''rate''' — частоту опроса со сменой значения в ШИМ-контроллере при выходе температуры из предыдущего диапазона (не обязательно делать это ежесекундно, чтоб и не дать перегреться, и не надоело листать портянку журнала);
#:*шаг '''gap_tmp''' между диапазонами температур;
#:*'''step''' — число сегментов, на которые будет разбит как диапазон регулируемых температур, так и шкала делений ШИМ-контроллера (вроде процентной, но не на 100, а на 255 делений);
#:*массив '''pwms''' про то, насколько разгоняться сиречь, какие эмпирически подобранные значения выставлять ШИМу в конкретных температурных диапазонах это не об/мин, как можно подумать, а нечто вроде процента от максимума — но не из 100, а из 255).
#:*'''whithin''' — допустимый разброс задаваемого значения ШИМ с не всегда одинаковым текущим, а также перехлёст температурных диапазонов, дабы вентилятор не дёргался на градус разницы, внося сумятицу в умы и сердца.
#:*'''whithin''' — допустимый разброс значений по границам сверки желаемого значения ШИМ со всегда немного отличающимся от заданного текущим (пытался задействовать ещё для перехлёста температурных диапазонов, дабы вентилятор не дёргался по одному градусу, внося сумятицу в ума и сердца — 1фиг дёргается, и пока не придумал, как победить);
#Запускать скрипт по таймеру не стал, оставил а-ля «резидентным» (см. цикл '''while'''), дабы между его запусками не бросать видюху в ручном режиме без управления (см. функцию '''setmode''').
#Сделал скрипт а-ля «резидентным» (цикл '''while''') — запускать по таймеру не стал, дабы между его запусками не оставлять видюху в ручном режиме без управления (см. функцию '''fanmode''').
==Результаты==
===Утро/вечер: веб-сёрфинг, общение, редактирование и пр.===
Переключение ШИМа на 20% (51) после примерно 5-минутного прогрева до 48°C, далее — колебания в пределах 50..55°C.


==Запускающий юнит==
Отход на перекус — температура примерно за то же время падает до 42°C, ШИМ обнуляется, далее — колебания как ночью.
<code>/lib/systemd/system/amdgpufan.service</code>:
<source lang="ini">
[Unit]
Description = AMD GPU fan control


[Service]
Будним днём с повышением забортной температуры системная тоже подрастает и гуляет в рамках 40°C+ без запуска вентиляторов.
ExecStart = /usr/local/sbin/amdgpufan
===Мёртвая петля (DeathLoop) на максималках===
Restart = on-failure
Колебания температуры между 59 и 76°C с прыжками ШИМ от 51 до 102, 153 и обратно:
RestartSec = 5
 
[Install]
WantedBy = default.target
</source>
Как включать юниты, все давно знают. :)
 
==Пример работы==
(дату-время и имя-пид процесса убрал для удобочитаемости)
===Вечер — веб-сёрфинг, редактирование и пр.===
Колебания в пределах 50°C при ШИМ 69.
 
===Запуск игры===
<pre>
<pre>
  60°C @ 69 PWM, changing to  90.
июн 03 21:17:40 comp.ill amdgpufan[1492297]: 66°C @153 PWM, switching to 102.
  59°C @ 89 PWM, changing to  70.
июн 03 21:17:43 comp.ill amdgpufan[1492297]: 72°C @102 PWM.
  60°C @ 69 PWM, changing to  90.
июн 03 21:17:46 comp.ill amdgpufan[1492297]: 72°C @102 PWM.
  57°C @ 89 PWM, changing to 70.
июн 03 21:17:49 comp.ill amdgpufan[1492297]: 70°C @102 PWM.
  54°C @ 69 PWM.
июн 03 21:17:52 comp.ill amdgpufan[1492297]: 76°C @102 PWM, switching to 153.
  59°C @ 69 PWM.
июн 03 21:17:55 comp.ill amdgpufan[1492297]: 75°C @153 PWM.
  62°C @ 69 PWM, changing to  90.
...
77°C @ 89 PWM.
июн 03 21:18:07 comp.ill amdgpufan[1492297]: 59°C @153 PWM.
июн 03 21:18:10 comp.ill amdgpufan[1492297]: 57°C @153 PWM, switching to  51.
</pre>
</pre>
===Активная фаза игры===
Насыщенная сцена:
<pre>
<pre>
  82°C @ 89 PWM, changing to 140.
июн 03 21:18:13 comp.ill amdgpufan[1492297]: 82°C @ 51 PWM.
  62°C @138 PWM, changing to  90.
июн 03 21:18:16 comp.ill amdgpufan[1492297]: 84°C @ 51 PWM.
  59°C @ 89 PWM, changing to 70.
июн 03 21:18:19 comp.ill amdgpufan[1492297]: 87°C @ 51 PWM, switching to 204.
62°C @ 69 PWM, changing to  90.
июн 03 21:18:22 comp.ill amdgpufan[1492297]: 87°C @204 PWM.
  60°C @ 89 PWM.
...
...
  61°C @ 89 PWM.
июн 03 21:18:43 comp.ill amdgpufan[1492297]:  87°C @204 PWM.
  62°C @ 89 PWM.
июн 03 21:18:46 comp.ill amdgpufan[1492297]:  78°C @204 PWM, switching to 153.
  58°C @ 89 PWM, changing to  70.
июн 03 21:18:49 comp.ill amdgpufan[1492297]:  59°C @153 PWM.
  60°C @ 69 PWM, changing to  90.
июн 03 21:18:52 comp.ill amdgpufan[1492297]:  83°C @153 PWM.
  75°C @ 89 PWM.
июн 03 21:18:55 comp.ill amdgpufan[1492297]: 85°C @153 PWM.
июн 03 21:18:58 comp.ill amdgpufan[1492297]: 85°C @153 PWM.
июн 03 21:19:01 comp.ill amdgpufan[1492297]: 86°C @153 PWM, switching to 204.
июн 03 21:19:04 comp.ill amdgpufan[1492297]:  86°C @204 PWM.
...
июн 03 21:19:49 comp.ill amdgpufan[1492297]: 85°C @204 PWM.
июн 03 21:19:52 comp.ill amdgpufan[1492297]: 60°C @204 PWM.
июн 03 21:19:55 comp.ill amdgpufan[1492297]:  58°C @204 PWM, switching to  51.
июн 03 21:19:58 comp.ill amdgpufan[1492297]:  57°C @ 51 PWM.
...
июн 03 21:20:22 comp.ill amdgpufan[1492297]:  58°C @ 51 PWM.
июн 03 21:20:25 comp.ill amdgpufan[1492297]:  75°C @ 51 PWM, switching to 153.
июн 03 21:20:28 comp.ill amdgpufan[1492297]: 75°C @153 PWM.
</pre>
</pre>
===Игра завершена===
Далее как в начале игры.
Плавное падение температуры:
 
<pre>
Судя по графику, выше 90°C не поднималось, обороты на максимум — тоже. ЦПУ греется сопоставимо, но почти всю игру 75..90°C.
53°C @ 89 PWM, changing to  70.
===Ночь===
  52°C @ 69 PWM.
41±2°C при нулевом ШИМе (шуме).
40°C @ 69 PWM.
 
39°C @ 69 PWM, changing to   0.
=Выводы=
40°C @  0 PWM, changing to  70.
[[Файл:Raven-Low.jpg|мини|SilverStone Raven v03]]
39°C @ 69 PWM, changing to   0.
До +30°C на улице большой внешний вентилятор сбоку более не нужен: игрушки на ультрах в высоком разрешении прогревают самый горячий компонент видюхи не выше 96°C, тогда как прежде и с вентилятором за сотку вылезало — теперь такое только при стресс-тестах, на которых до того система попросту аварийно отключалась. Как будет в самую жару, опробовать пока не довелось, но по результатам отчитаюсь.
39°C @  0 PWM.
 
</pre>
Когда не ломанная / не чиненная железяка работает не так, как ожидается, порой на помощь спешат чип и… программные средства. Пусть без рюшечек и фантиков, зато задача решена на системном уровне. Ну, и есть надежда, что дружелюбного софта тоже не придётся долго ждать.
Ночью колебания 35-38°C с отключёнными вентиляторами видюхи.
 
=Итоги=
…А после всех потуг открыл для себя {{cmd|fancontrol}}, который:
*запускается как служба;
*распоряжается всеми ШИМ-вентиляторами, подключёнными к мат.плате;
*настраивается утилиткой <code>pwmconfig</code>;
*в дальнейшем правится вручную через конфиг.
Главное — правильно сопоставить конкретные вентиляторы остужаемым компонентам, не обязательно встроенным в материнку. При этом зависимость от датчиков вращения столь же необязательна. Вот пример моего конфига (уже под корпус Raven v03, ''см. ниже''):
{|class="mw-collapsible mw-collapsed wikitable"
!/etc/fancontrol &nbsp;
|-
|<source lang=bash>
# вентилятор    об/мин      -/+ШИМ дБ/шум
##########################################
# AiGo          700..1700  48/80  2
# ArcticCool    450..1650  54/60  2
# Titan        300..2150  80/84   1
# Lucifer      650..1500  85/87  4
# AeroCool      550..1300  85/90  3
# Reeven        350..1700  80/95   6
# ID-Cooling    500..1800  65/68  5
# RX-6700XT    450..3200  55/68  7


===Утро — вход в систему===
# hwmon    разъём вентилятор где
Веб-сёрфинг, редактирование и пр.:
##########################################
<pre>
# 2/pwm1    Pump    AiGo        верх+морда
  40°C @ 0 PWM, changing to  70.
# 2/pwm2    CPU    ID-Cooling  проц
41°C @ 69 PWM.
# 2/pwm3    Sys1    Reeven      бок, hddfancontrol
</pre>
# 2/pwm4    Sys2    AiGo        тыл
Далее — колебания 42-55°C при ШИМ 69.
# 2/pwm5    Sys3    Lucifer    крышка
===Перезапуск скрипта в жару===
# 2/temp7  ЦПУ
По нулевому значению ШИМ на старте видно, что автонастройка не включает вентиляторы как минимум до 50°C:
# 0/pwm1    видюха: 1) ГПУ, 2) переход, 3) память
<pre>
мая 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.
</pre>


===Игра по жаре===
INTERVAL=10
<pre>
DEVPATH=   hwmon0=devices/pci0000:00/0000:00:03.1/0000:2d:00.0/0000:2e:00.0/0000:2f:00.0  hwmon1=devices/pci0000:00/0000:00:18.3  hwmon2=devices/platform/nct6775.2592
92°C @ 87 PWM, changing to 140.
DEVNAME=   hwmon0=amdgpu                  hwmon1=k10temp                  hwmon2=nct6797
</pre>
FCTEMPS=    hwmon0/pwm1=hwmon0/temp2_input  hwmon2/pwm1=hwmon2/temp7_input  hwmon2/pwm2=hwmon2/temp7_input  hwmon2/pwm4=hwmon0/temp2_input  hwmon2/pwm5=hwmon0/temp2_input
Далее колебания на 90+°C при ШИМ 138.
FCFANS=    hwmon0/pwm1=hwmon0/fan1_input  hwmon2/pwm1=hwmon2/fan1_input  hwmon2/pwm2=hwmon2/fan2_input  hwmon2/pwm4=hwmon2/fan4_input  hwmon2/pwm5=hwmon2/fan5_input
MINTEMP=    hwmon0/pwm1=55                  hwmon2/pwm1=45                  hwmon2/pwm2=45                  hwmon2/pwm4=48                  hwmon2/pwm5=48
MAXTEMP=    hwmon0/pwm1=85                  hwmon2/pwm1=80                  hwmon2/pwm2=80                  hwmon2/pwm4=85                  hwmon2/pwm5=85
MINSTOP=    hwmon0/pwm1=55                  hwmon2/pwm1=65                  hwmon2/pwm2=65                  hwmon2/pwm4=65                  hwmon2/pwm5=85
MINSTART=  hwmon0/pwm1=63                  hwmon2/pwm1=68                  hwmon2/pwm2=68                  hwmon2/pwm4=68                  hwmon2/pwm5=87
</source>
|}
'''Обратите внимание:''' знак равенства не должен отделяться пропусками от имени опции, а вот значения, которых может быть более одного — вполне себе.


=Выводы=
<u>P.S.</u> И ещё поменял корпус на огромный AeroCool xPredator FullTower с кучей больших вентиляторов (6х14 и 2х22 см) — теперь совсем красота!
На данный момент ночью, по прохладе, большой внешний вентилятор уже точно не нужен: игрушки на ультрах в высоком разрешении прогревают самый горячий компонент видюхи не выше 96 градусов, тогда как прежде и с вентилятором за сотку вылезало. Вечером в пределах +30 на улице тоже обошёлся без вентилятора. Как оно в дневную жару, опробовать пока не довелось, но по результатам отчитаюсь.


Когда не ломанная / не чиненная железяка работает не так, как ожидается, порой на помощь спешат чип и... программные средства. Пусть без рюшечек и фантиков, зато задача решена на системном уровне. Ну, и есть надежда, что дружелюбного софта тоже не придётся долго ждать.
<u>UPD:</u> Поменял и этот на не хуже продуваемый, но более компактный и удобный SilverStone Raven v03 (мат.плата в нём развёрнута на 90° по часовой &mdash; портами вверх).


=Послесловие=
А ведь есть ещё варианты разгона с понижением напруги [https://www.cryptoprofi.info/?p=5128 типа такого]. С учётом побеждённого перегрева, отчего б и его не задействовать... :)
=Обратная связь=
=Обратная связь=
[https://t.me/gbIMoBou @gbIMoBou]
*[https://t.me/gbIMoBou @gbIMoBou]
 
*[[Участник:Дым#Заметки|Другие статьи]]
[[Участник:Дым|Другие статьи]]
{{Category navigation|title=Системному администратору|category=Admin|sortkey={{SUBPAGENAME}}}}
{{Category navigation|title=Системному администратору|category=Admin|sortkey={{SUBPAGENAME}}}}
[[Категория:Admin]]
[[Категория:Admin]]
[[Категория:Hardware]]
[[Категория:HCL]]

Текущая версия от 08:46, 27 июля 2023

Zalman Z1

Введение

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

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

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

Реализация

AeroCool xPredator FullTower

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

При этом для командной строки нарубинено да напитонено всякого, но к чему плодить сущности, если всё можно сделать перманентно доступным шеллом? Проникся довольно замороченным решением amdgpu-fancontrol и по образу/подобию слепил на скорую руку собственный упрощённый вариант, для которого понадобится тройка файлов — скрипт да конфиг c юнитом к нему (выложены на ГитХаб).

1) Файл настроек

/etc/sysconfig/amdgpufan  
# restart service amdgpufan if config changed
card=0          # vega rather has number 1
rate=3          # check frequency
step=5          # min to max divider
within=2        # temperature borders and pwm diff tolerance
min_tmp=45      # no need cooling lower
sensor=junction # 'edge' (gpu), 'mem' or 'junction' (hottest one)

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

/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

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

3) Сам скрипт

/usr/local/sbin/amdgpufan  
#!/bin/sh

[ $UID -eq 0 ] || { # Check user permissions.
    echo "Writing to /sys requires root privileges."
    exit 1
}

## User defaults if config absend ################################
card=0          # vega rather has number 1
rate=3          # check frequency
step=5          # min to max divider
within=2        # temperature borders and pwm diff tolerance
min_tmp=45      # no need cooling lower
sensor=junction # 'edge' (gpu), 'mem' or 'junction' (hottest one)

config=/etc/sysconfig/amdgpufan
[ -f $config -a -s $config ] && source $config ||
echo "User settings not found, using default values."

case $sensor in
    junction) # let's add some degrees to most hot sensor
         let min_tmp+=5
         sensor=2;;
    edge)sensor=1;;
    mem) sensor=3;;
esac

## System variables ##############################################
gpuinfo=/sys/kernel/debug/dri/$card/amdgpu_pm_info
dev_dir=/sys/class/drm/card$card/device
sys_dir=`ls -d $dev_dir/hwmon/*`
sys_lvl=${dev_dir}/power_dpm_force_performance_level
sys_clk=${dev_dir}/pp_od_clk_voltage
sys_tmp=${sys_dir}/temp${sensor}_input
sys_pwm=${sys_dir}/pwm1
sys_fan=${sys_pwm}_enable

## Calculated variables ##########################################
part=$[step-2] # loops' divider: steps num except first and last
# Achievable frequencies for gpu & mem:
mhz=(`awk '/^(M|S)/{gsub("Mhz","");print $3}' $sys_clk | sort -V`)
max_tmp=$[`cat $sys_dir/temp*_crit | sort -V | head -1`/1000]
max_pwm=`cat ${sys_pwm}_max`
min_pwm=`cat ${sys_pwm}_min`
gap_pwm=$[(max_pwm-min_pwm)/step]
gap_tmp=$[(max_tmp-min_tmp)/step]

reset(){ # Sudden break.
    printf "Exiting and s"
    setmode auto
    exit 0
}

setmode(){ # Change as mode as gpu & mem frequency.
    echo "etting clock & fan mode to '$1'."
    case $1 in
        auto)   mode=2;;
        manual) mode=1
                echo m 1 ${mhz[0]}  >$sys_clk
                echo s 1 ${mhz[1]}  >$sys_clk
        ;;
    esac
    echo $mode  >$sys_fan
    echo $1     >$sys_lvl
}

main(){ # Whole magic.
    cur_pwm=`cat $sys_pwm`
    cur_tmp=$[`cat $sys_tmp`/1000]
    [[ `cat $sys_fan` -eq 1 ]] || {
        printf "S"
        setmode manual
    }
    if [[ $cur_tmp -gt $max_tmp ]]; then
        echo "$cur_tmp°C exceeds critical, set 100% blowing."
        new_pwm=$max_pwm
    elif [[ $cur_tmp -le $min_tmp ]]; then
        new_pwm=$min_pwm
    else
        for i in `seq 0 $part`; do
            [[ $cur_tmp -ge $[min_tmp+gap_tmp*i]     ]] &&
            [[ $cur_tmp -le $[min_tmp+gap_tmp*(i+1)] ]] && {
                new_pwm=$[min_pwm+gap_pwm*(i+1)]
                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.
        for i in `seq 0 $part`; do
            [[ $cur_tmp -ge $[min_tmp+gap_tmp*i-within] ]] &&
            [[ $cur_tmp -le $[min_tmp+gap_tmp*i+within] ]] && {
                echo "."
                break
            }
        done || {
            printf ", switching 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. Пользовательскими переменными из конфига задаю:
    • card — № видюхи (судя по статьям от спецов, при наличии встройки оная будет пронумерована единичкой);
    • min_tmp — температуру, ниже которой мослать вентилятором бессмысленно (с завода вентилятор не включается до 52°C процессора, а при остывании останавливается на 46°C);
    • sensor — какой из датчиков «пасти»: процессора, самый холодный (памяти) или самый горячий (температуры перехода), однако max_tmp выбираю минимальную из критических;
    • rate — частоту опроса со сменой значения в ШИМ-контроллере при выходе температуры из предыдущего диапазона (не обязательно делать это ежесекундно, чтоб и не дать перегреться, и не надоело листать портянку журнала);
    • step — число сегментов, на которые будет разбит как диапазон регулируемых температур, так и шкала делений ШИМ-контроллера (вроде процентной, но не на 100, а на 255 делений);
    • whithin — допустимый разброс задаваемого значения ШИМ с не всегда одинаковым текущим, а также перехлёст температурных диапазонов, дабы вентилятор не дёргался на градус разницы, внося сумятицу в умы и сердца.
  2. Запускать скрипт по таймеру не стал, оставил а-ля «резидентным» (см. цикл while), дабы между его запусками не бросать видюху в ручном режиме без управления (см. функцию setmode).

Результаты

Утро/вечер: веб-сёрфинг, общение, редактирование и пр.

Переключение ШИМа на 20% (51) после примерно 5-минутного прогрева до 48°C, далее — колебания в пределах 50..55°C.

Отход на перекус — температура примерно за то же время падает до 42°C, ШИМ обнуляется, далее — колебания как ночью.

Будним днём с повышением забортной температуры системная тоже подрастает и гуляет в рамках 40°C+ без запуска вентиляторов.

Мёртвая петля (DeathLoop) на максималках

Колебания температуры между 59 и 76°C с прыжками ШИМ от 51 до 102, 153 и обратно:

июн 03 21:17:40 comp.ill amdgpufan[1492297]:  66°C @153 PWM, switching to 102.
июн 03 21:17:43 comp.ill amdgpufan[1492297]:  72°C @102 PWM.
июн 03 21:17:46 comp.ill amdgpufan[1492297]:  72°C @102 PWM.
июн 03 21:17:49 comp.ill amdgpufan[1492297]:  70°C @102 PWM.
июн 03 21:17:52 comp.ill amdgpufan[1492297]:  76°C @102 PWM, switching to 153.
июн 03 21:17:55 comp.ill amdgpufan[1492297]:  75°C @153 PWM.
...
июн 03 21:18:07 comp.ill amdgpufan[1492297]:  59°C @153 PWM.
июн 03 21:18:10 comp.ill amdgpufan[1492297]:  57°C @153 PWM, switching to  51.

Насыщенная сцена:

июн 03 21:18:13 comp.ill amdgpufan[1492297]:  82°C @ 51 PWM.
июн 03 21:18:16 comp.ill amdgpufan[1492297]:  84°C @ 51 PWM.
июн 03 21:18:19 comp.ill amdgpufan[1492297]:  87°C @ 51 PWM, switching to 204.
июн 03 21:18:22 comp.ill amdgpufan[1492297]:  87°C @204 PWM.
...
июн 03 21:18:43 comp.ill amdgpufan[1492297]:  87°C @204 PWM.
июн 03 21:18:46 comp.ill amdgpufan[1492297]:  78°C @204 PWM, switching to 153.
июн 03 21:18:49 comp.ill amdgpufan[1492297]:  59°C @153 PWM.
июн 03 21:18:52 comp.ill amdgpufan[1492297]:  83°C @153 PWM.
июн 03 21:18:55 comp.ill amdgpufan[1492297]:  85°C @153 PWM.
июн 03 21:18:58 comp.ill amdgpufan[1492297]:  85°C @153 PWM.
июн 03 21:19:01 comp.ill amdgpufan[1492297]:  86°C @153 PWM, switching to 204.
июн 03 21:19:04 comp.ill amdgpufan[1492297]:  86°C @204 PWM.
...
июн 03 21:19:49 comp.ill amdgpufan[1492297]:  85°C @204 PWM.
июн 03 21:19:52 comp.ill amdgpufan[1492297]:  60°C @204 PWM.
июн 03 21:19:55 comp.ill amdgpufan[1492297]:  58°C @204 PWM, switching to  51.
июн 03 21:19:58 comp.ill amdgpufan[1492297]:  57°C @ 51 PWM.
...
июн 03 21:20:22 comp.ill amdgpufan[1492297]:  58°C @ 51 PWM.
июн 03 21:20:25 comp.ill amdgpufan[1492297]:  75°C @ 51 PWM, switching to 153.
июн 03 21:20:28 comp.ill amdgpufan[1492297]:  75°C @153 PWM.

Далее как в начале игры.

Судя по графику, выше 90°C не поднималось, обороты на максимум — тоже. ЦПУ греется сопоставимо, но почти всю игру 75..90°C.

Ночь

41±2°C при нулевом ШИМе (шуме).

Выводы

SilverStone Raven v03

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

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

Итоги

…А после всех потуг открыл для себя fancontrol, который:

  • запускается как служба;
  • распоряжается всеми ШИМ-вентиляторами, подключёнными к мат.плате;
  • настраивается утилиткой pwmconfig;
  • в дальнейшем правится вручную через конфиг.

Главное — правильно сопоставить конкретные вентиляторы остужаемым компонентам, не обязательно встроенным в материнку. При этом зависимость от датчиков вращения столь же необязательна. Вот пример моего конфига (уже под корпус Raven v03, см. ниже):

/etc/fancontrol  
# вентилятор    об/мин      -/+ШИМ  дБ/шум
##########################################
# AiGo          700..1700   48/80   2
# ArcticCool    450..1650   54/60   2
# Titan         300..2150   80/84   1
# Lucifer       650..1500   85/87   4
# AeroCool      550..1300   85/90   3
# Reeven        350..1700   80/95   6
# ID-Cooling    500..1800   65/68   5
# RX-6700XT     450..3200   55/68   7

# hwmon     разъём  вентилятор  где
##########################################
# 2/pwm1    Pump    AiGo        верх+морда
# 2/pwm2    CPU     ID-Cooling  проц
# 2/pwm3    Sys1    Reeven      бок, hddfancontrol
# 2/pwm4    Sys2    AiGo        тыл
# 2/pwm5    Sys3    Lucifer     крышка
# 2/temp7   ЦПУ
# 0/pwm1    видюха: 1) ГПУ, 2) переход, 3) память

INTERVAL=10
DEVPATH=    hwmon0=devices/pci0000:00/0000:00:03.1/0000:2d:00.0/0000:2e:00.0/0000:2f:00.0   hwmon1=devices/pci0000:00/0000:00:18.3  hwmon2=devices/platform/nct6775.2592
DEVNAME=    hwmon0=amdgpu                   hwmon1=k10temp                  hwmon2=nct6797
FCTEMPS=    hwmon0/pwm1=hwmon0/temp2_input  hwmon2/pwm1=hwmon2/temp7_input  hwmon2/pwm2=hwmon2/temp7_input  hwmon2/pwm4=hwmon0/temp2_input  hwmon2/pwm5=hwmon0/temp2_input
FCFANS=     hwmon0/pwm1=hwmon0/fan1_input   hwmon2/pwm1=hwmon2/fan1_input   hwmon2/pwm2=hwmon2/fan2_input   hwmon2/pwm4=hwmon2/fan4_input   hwmon2/pwm5=hwmon2/fan5_input
MINTEMP=    hwmon0/pwm1=55                  hwmon2/pwm1=45                  hwmon2/pwm2=45                  hwmon2/pwm4=48                  hwmon2/pwm5=48
MAXTEMP=    hwmon0/pwm1=85                  hwmon2/pwm1=80                  hwmon2/pwm2=80                  hwmon2/pwm4=85                  hwmon2/pwm5=85
MINSTOP=    hwmon0/pwm1=55                  hwmon2/pwm1=65                  hwmon2/pwm2=65                  hwmon2/pwm4=65                  hwmon2/pwm5=85
MINSTART=   hwmon0/pwm1=63                  hwmon2/pwm1=68                  hwmon2/pwm2=68                  hwmon2/pwm4=68                  hwmon2/pwm5=87

Обратите внимание: знак равенства не должен отделяться пропусками от имени опции, а вот значения, которых может быть более одного — вполне себе.

P.S. И ещё поменял корпус на огромный AeroCool xPredator FullTower с кучей больших вентиляторов (6х14 и 2х22 см) — теперь совсем красота!

UPD: Поменял и этот на не хуже продуваемый, но более компактный и удобный SilverStone Raven v03 (мат.плата в нём развёрнута на 90° по часовой — портами вверх).

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