Управление вентилятором Radeon RX-6xx0: различия между версиями
Дым (обсуждение | вклад) (Новая страница: «Вдохновлённый решением одного [https://github.com/WieWaldi/amdgpu-fancontrol немца], сваял собственный сильно упрощённый вариант. Понадобится создать два файла. #Собственно скрипт запуска <code>/usr/local/sbin/amdgpufan</code>: #:<source lang="bash"> #!/bin/bash # amdgpufan [ $UID -eq 0 ] || { # Check root privileges. echo "Writing to...») |
Дым (обсуждение | вклад) (→Итоги) |
||
(не показано 196 промежуточных версий этого же участника) | |||
Строка 1: | Строка 1: | ||
[[Файл:1.Zalman Z1.jpg|мини|Zalman Z1]] | |||
=Введение= | |||
Столкнулся с проблемой перегрева видюхи RX-6700XT на игровых нагрузках — и не только её самой, поскольку она ведь и вокруг себя изрядно греет. | |||
*Процессор прямо над нею кипятится — мéста между видюхой, крышкой и стенками отнюдь не завались. | |||
*М2-накопитель посреди видюхи и проца тоже знатно подгорает — хоть и с радиатором, и от проц-кулера на него дует… горячим. | |||
*Дополнительным винчестерам в корзине, вставленной в пространство 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 | ||
|- | |||
|<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 | |||
|- | |||
|<source lang="ini"> | |||
[Unit] | |||
Description = AMD GPU fan control | |||
[Service] | |||
ExecStart = /usr/local/sbin/amdgpufan | |||
Restart = on-failure | |||
RestartSec = 5 | |||
[ $UID -eq 0 ] || { # Check | [Install] | ||
WantedBy = default.target | |||
</source> | |||
|} | |||
Как включать юниты, все давно знают. :) | |||
===3) Сам скрипт=== | |||
{|class="mw-collapsible mw-collapsed wikitable" | |||
!/usr/local/sbin/amdgpufan | |||
|- | |||
|<source lang="bash"> | |||
#!/bin/sh | |||
[ $UID -eq 0 ] || { # Check user permissions. | |||
echo "Writing to /sys requires root privileges." | echo "Writing to /sys requires root privileges." | ||
exit 1 | exit 1 | ||
} | } | ||
########################### | ## User defaults if config absend ################################ | ||
## | card=0 # vega rather has number 1 | ||
card=0 | rate=3 # check frequency | ||
rate=5 | step=5 # min to max divider | ||
min_tmp= | 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." | |||
sys_tmp=${sys_dir}/ | 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_pwm=${sys_dir}/pwm1 | ||
sys_fan=${sys_pwm}_enable | sys_fan=${sys_pwm}_enable | ||
## Calculated variables ########################################## | |||
max_tmp=$[`cat $ | 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= | gap_pwm=$[(max_pwm-min_pwm)/step] | ||
gap_tmp=$[(max_tmp-min_tmp)/step] | |||
reset(){ | reset(){ # Sudden break. | ||
printf "Exiting and | printf "Exiting and s" | ||
setmode auto | |||
exit 0 | exit 0 | ||
} | } | ||
setmode(){ # Change as mode as gpu & mem frequency. | |||
echo "etting clock & fan mode to '$1'." | |||
case $1 in | case $1 in | ||
auto) mode=2;; | auto) mode=2;; | ||
manual) mode=1 | |||
echo m 1 ${mhz[0]} >$sys_clk | |||
echo s 1 ${mhz[1]} >$sys_clk | |||
;; | |||
esac | esac | ||
echo | echo $mode >$sys_fan | ||
echo $ | echo $1 >$sys_lvl | ||
} | } | ||
main(){ | main(){ # Whole magic. | ||
cur_pwm=`cat $sys_pwm` | cur_pwm=`cat $sys_pwm` | ||
cur_tmp=$[`cat $sys_tmp`/1000] | cur_tmp=$[`cat $sys_tmp`/1000] | ||
[[ `cat $sys_fan` -eq 1 ]] || { | [[ `cat $sys_fan` -eq 1 ]] || { | ||
printf " | printf "S" | ||
setmode manual | |||
} | } | ||
if | if [[ $cur_tmp -gt $max_tmp ]]; then | ||
echo "$cur_tmp°C | echo "$cur_tmp°C exceeds critical, set 100% blowing." | ||
new_pwm=$max_pwm | new_pwm=$max_pwm | ||
elif [[ $cur_tmp -le $min_tmp ]]; then | |||
new_pwm=$min_pwm | |||
else | 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 | fi | ||
printf "%3d°C @%3d PWM" $cur_tmp $cur_pwm | printf "%3d°C @%3d PWM" $cur_tmp $cur_pwm | ||
[[ $cur_pwm -ge $[new_pwm- | [[ $cur_pwm -ge $[new_pwm-within] ]] && | ||
[[ $cur_pwm -le | [[ $cur_pwm -le $[new_pwm+within] ]] && | ||
echo "." || { | echo "." || { # Change PWM if differ. | ||
printf ", | 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. | trap "reset" SIGINT SIGTERM # Handle signals. | ||
while :; do # | while :; do # Go on! | ||
main | main | ||
sleep ${rate}s | sleep ${rate}s | ||
done | done | ||
</source> | </source> | ||
# | |} | ||
===Пояснения=== | |||
#Пользовательскими переменными из конфига задаю: | |||
#:*'''card''' — № видюхи (судя по статьям от спецов, при наличии встройки оная будет пронумерована единичкой); | |||
#:*'''min_tmp''' — температуру, ниже которой мослать вентилятором бессмысленно (с завода вентилятор не включается до 52°C процессора, а при остывании останавливается на 46°C); | |||
#:*'''sensor''' — какой из датчиков «пасти»: процессора, самый холодный (памяти) или самый горячий (температуры перехода), однако '''max_tmp''' выбираю минимальную из критических; | |||
#:*'''rate''' — частоту опроса со сменой значения в ШИМ-контроллере при выходе температуры из предыдущего диапазона (не обязательно делать это ежесекундно, чтоб и не дать перегреться, и не надоело листать портянку журнала); | |||
#:*'''step''' — число сегментов, на которые будет разбит как диапазон регулируемых температур, так и шкала делений ШИМ-контроллера (вроде процентной, но не на 100, а на 255 делений); | |||
#:*'''whithin''' — допустимый разброс задаваемого значения ШИМ с не всегда одинаковым текущим, а также перехлёст температурных диапазонов, дабы вентилятор не дёргался на градус разницы, внося сумятицу в умы и сердца. | |||
#Запускать скрипт по таймеру не стал, оставил а-ля «резидентным» (см. цикл '''while'''), дабы между его запусками не бросать видюху в ручном режиме без управления (см. функцию '''setmode'''). | |||
==Результаты== | |||
===Утро/вечер: веб-сёрфинг, общение, редактирование и пр.=== | |||
Переключение ШИМа на 20% (51) после примерно 5-минутного прогрева до 48°C, далее — колебания в пределах 50..55°C. | |||
Отход на перекус — температура примерно за то же время падает до 42°C, ШИМ обнуляется, далее — колебания как ночью. | |||
Будним днём с повышением забортной температуры системная тоже подрастает и гуляет в рамках 40°C+ без запуска вентиляторов. | |||
===Мёртвая петля (DeathLoop) на максималках=== | |||
Колебания температуры между 59 и 76°C с прыжками ШИМ от 51 до 102, 153 и обратно: | |||
<pre> | |||
июн 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. | |||
</pre> | |||
Насыщенная сцена: | |||
<pre> | |||
июн 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. | |||
</pre> | |||
Далее как в начале игры. | |||
Судя по графику, выше 90°C не поднималось, обороты на максимум — тоже. ЦПУ греется сопоставимо, но почти всю игру 75..90°C. | |||
===Ночь=== | |||
41±2°C при нулевом ШИМе (шуме). | |||
=Выводы= | |||
[[Файл:Raven-Low.jpg|мини|SilverStone Raven v03]] | |||
До +30°C на улице большой внешний вентилятор сбоку более не нужен: игрушки на ультрах в высоком разрешении прогревают самый горячий компонент видюхи не выше 96°C, тогда как прежде и с вентилятором за сотку вылезало — теперь такое только при стресс-тестах, на которых до того система попросту аварийно отключалась. Как будет в самую жару, опробовать пока не довелось, но по результатам отчитаюсь. | |||
Когда не ломанная / не чиненная железяка работает не так, как ожидается, порой на помощь спешат чип и… программные средства. Пусть без рюшечек и фантиков, зато задача решена на системном уровне. Ну, и есть надежда, что дружелюбного софта тоже не придётся долго ждать. | |||
=Итоги= | |||
…А после всех потуг открыл для себя {{cmd|fancontrol}}, который: | |||
*запускается как служба; | |||
*распоряжается всеми ШИМ-вентиляторами, подключёнными к мат.плате; | |||
*настраивается утилиткой <code>pwmconfig</code>; | |||
*в дальнейшем правится вручную через конфиг. | |||
Главное — правильно сопоставить конкретные вентиляторы остужаемым компонентам, не обязательно встроенным в материнку. При этом зависимость от датчиков вращения столь же необязательна. Вот пример моего конфига (уже под корпус Raven v03, ''см. ниже''): | |||
{|class="mw-collapsible mw-collapsed wikitable" | |||
!/etc/fancontrol | |||
|- | |||
|<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 разъём вентилятор где | |||
########################################## | |||
# 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 | |||
</source> | </source> | ||
|} | |||
'''Обратите внимание:''' знак равенства не должен отделяться пропусками от имени опции, а вот значения, которых может быть более одного — вполне себе. | |||
<u>P.S.</u> И ещё поменял корпус на огромный AeroCool xPredator FullTower с кучей больших вентиляторов (6х14 и 2х22 см) — теперь совсем красота! | |||
<u>UPD:</u> Поменял и этот на не хуже продуваемый, но более компактный и удобный SilverStone Raven v03 (мат.плата в нём развёрнута на 90° по часовой — портами вверх). | |||
=Обратная связь= | |||
*[https://t.me/gbIMoBou @gbIMoBou] | |||
*[[Участник:Дым#Заметки|Другие статьи]] | |||
{{Category navigation|title=Системному администратору|category=Admin|sortkey={{SUBPAGENAME}}}} | |||
[[Категория:Admin]] | |||
[[Категория:Hardware]] | |||
[[Категория:HCL]] |
Текущая версия от 11:46, 27 июля 2023
Введение
Столкнулся с проблемой перегрева видюхи RX-6700XT на игровых нагрузках — и не только её самой, поскольку она ведь и вокруг себя изрядно греет.
- Процессор прямо над нею кипятится — мéста между видюхой, крышкой и стенками отнюдь не завались.
- М2-накопитель посреди видюхи и проца тоже знатно подгорает — хоть и с радиатором, и от проц-кулера на него дует… горячим.
- Дополнительным винчестерам в корзине, вставленной в пространство 5-дюймовых отсеков, жарко и душно.
- Да и тем, что в нижних 3,5-дюймовых, ни разу не уютно.
До некоторой степени спасает вариант поставить перед открытой крышкой системника большой настольный вентилятор (см. фото) — для всего, кроме самой видюхи: она ж к нему краем, и толку почти ноль. А заводская авторегулировка видюхиного ШИМа как-то не особо способствует её охлаждению даже зимой, о жаре за бортом вовсе молчу.
Реализация
Пошарив по просторам, нарыл массу графических «мониторилок» — но ни одной «крутилки» именно для АМД, хотя для ненаВидии — завались (один лишь «позеленевший от зависти» чего стóит). И это невзирая на то, что всё нужное доступно прямо из системы, без нужды ковыряться в проприетарщине… Странное дело.
При этом для командной строки нарубинено да напитонено всякого, но к чему плодить сущности, если всё можно сделать перманентно доступным шеллом? Проникся довольно замороченным решением 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
|
Пояснения
- Пользовательскими переменными из конфига задаю:
- card — № видюхи (судя по статьям от спецов, при наличии встройки оная будет пронумерована единичкой);
- min_tmp — температуру, ниже которой мослать вентилятором бессмысленно (с завода вентилятор не включается до 52°C процессора, а при остывании останавливается на 46°C);
- sensor — какой из датчиков «пасти»: процессора, самый холодный (памяти) или самый горячий (температуры перехода), однако max_tmp выбираю минимальную из критических;
- rate — частоту опроса со сменой значения в ШИМ-контроллере при выходе температуры из предыдущего диапазона (не обязательно делать это ежесекундно, чтоб и не дать перегреться, и не надоело листать портянку журнала);
- step — число сегментов, на которые будет разбит как диапазон регулируемых температур, так и шкала делений ШИМ-контроллера (вроде процентной, но не на 100, а на 255 делений);
- whithin — допустимый разброс задаваемого значения ШИМ с не всегда одинаковым текущим, а также перехлёст температурных диапазонов, дабы вентилятор не дёргался на градус разницы, внося сумятицу в умы и сердца.
- Запускать скрипт по таймеру не стал, оставил а-ля «резидентным» (см. цикл 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 при нулевом ШИМе (шуме).
Выводы
До +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° по часовой — портами вверх).