Если ноутбук с гибридной графикой разряжается за два часа, а nvidia-smi в простое показывает 30–40 Вт, дело не в системе, а в том, что дискретная карта не засыпает. Разбираю, как усыпить NVIDIA через параметр NVreg_DynamicPowerManagement, как отключить её по ACPI, и почему режим «только встроенная графика» в BIOS — самый честный способ сэкономить.
Дискретная карта на Optimus-ноутбуках живёт в двух состояниях: D0 — полностью включена, D3cold — обесточена. Пока она в D0, даже без единого процесса, потребление держится в районе 5–10 Вт, вентиляторы раскручиваются, корпус греется. Батареи хватает на 3–4 часа вместо 8–10.
Вторая причина — монитор. Если кабель подключён к порту, который физически заведен на NVIDIA, карта обязана оставаться в D0: она отдаёт изображение. Никакая экономия тут не поможет, пока внешний экран или зарядка не отключены.
Третья — включённый persistence mode. Он держит драйвер и карту инициализированными, чтобы пробуждение было мгновенным. Плата этого удобства — карта не уходит в D3cold вообще. Если экономия важнее скорости пробуждения, persistence mode выключают:
sudo nvidia-smi -pm 0
Четвёртая причина глубже всех: режим MUX. В ноутбуках с Optimus дискретная карта может быть подключена к встроенному экрану через собственный мультиплексор. В таком варианте питание карты физически не отключается, D3cold недостижим, и единственный способ сэкономить — переключить BIOS в режим «только встроенная графика» либо на ноутбуках с Advanced Optimus переключить MUX из операционной системы.
Начни с PCIe-стета power state — это честный ответ, без догадок:
lspci -nnk | grep -A3 -E 'VGA|3D controller'
cat /sys/bus/pci/devices/0000:01:00.0/power_state
D0 — карта натянет энергию, D3cold — обесточена и потребление почти ноль, D3hot — промежуточное состояние, питание частично есть, экономии почти нет.
Состояние самой NVIDIA смотрится так:
nvidia-smi --query-gpu=name,pstate,power.draw,clocks.sm --format=csv
pstate P8 или P0 у карты, которая ничего не делает, — повод настраивать питание. Расход батареи виден на уровне системы:
cat /sys/class/power_supply/BAT0/power_now
upower --dump | grep -A4 'energy-rate'
Классическая схема — офлоад в переменных окружения. prime-run перед игрой выставляет __GLX_VENDOR_LIBRARY_NAME, __NV_PRIME_RENDER_OFFLOAD и __GLFW_LIBRARY_PATH, и процесс уходит на NVIDIA. Про остальные тонкости — Prime, Run и Steam на гибридной графике.
Остаток мощности можно держать под рукой и без перезапуска: prime-select ondemand переводит систему в режим экономии, prime-select off полностью отключает dGPU в текущей сессии.
Два параметра ядра стоит зафиксировать сразу. Первый включает эмуляцию fbdev на карте NVIDIA — без неё консоль может не отрисоваться на нужном выходе, и это же лечит часть проблем с чёрным экраном и nomodeset. Второй убирает nouveau из уравнения, если он мешает:
# /etc/modprobe.d/blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0
# /etc/modprobe.d/nvidia-fbdev.conf
options nvidia_drm fbdev=1
После правок initramfs обязателен: sudo mkinitcpio -P, затем перезагрузка. Если в lsmod nouveau всё ещё есть, новый initramfs не подхватился.
Отдельно про nouveau: на ядрах 6.2+ у модуля есть runpm=1 — пробуждение по требованию клиентов. Стоит включить, если карта досталась в связке со свободным драйвером.
Это главный рычаг, который реально усыпляет карту без внешнего монитора. Один файл — и карта уходит в D3cold, как только все клиенты отцепились:
# /etc/modprobe.d/nvidia-power.conf
options nvidia NVreg_DynamicPowerManagement=0x02
Значения читаются как битовая маска: 0x00 полностью выключает механику, 0x01 — грубый режим, 0x02 — более тонкий, его обычно и советуют для Optimus-ноутбуков, 0x03 встречается как комбинация флагов в новых драйверах. После initramfs и перезагрузки проверь результат:
nvidia-smi -q | grep -i -A2 'Dynamic Power'
cat /sys/bus/pci/devices/0000:01:00.0/power_state
Не сработало — смотри dmesg:
dmesg | grep -i -E 'nvidia|d3cold|acpi' | tail -40
Две частые причины провала: nouveau всё ещё загружен и живёт в одной связке с проприетарным драйвером, либо к карте подключён монитор через HDMI/DisplayPort. Ещё одна тонкость — встроенный дисплей на многих ноутбуках физически привязан к NVIDIA, и D3cold там просто не активируется.
Если NVIDIA не нужна вообще, надёжнее выключить её на уровне прошивки. bbswitch для этого давно не нужен — модуль не собирается под свежие ядра, а апстримная поддержка в ядре так и не появилась. Остаётся acpi_call, который умеет дёргать ACPI-метод:
sudo pacman -S acpi_call
sudo modprobe acpi_call
ls /sys/firmware/acpi/calls
В списке ищи путь вроде _SB.PCI0.PEG0.SWRT.DSTS. Значение 1 — карта обесточена, 0 — включена обратно:
echo 1 | sudo tee /sys/firmware/acpi/calls/_SB._SB.PCI0.PEG0.SWRT.DSTS
Имя метода отличается между ноутбуками, поэтому всегда смотри ls перед записью. Нужен именно тот путь, где в имени есть SWRT (switch) — это и есть переключатель питания карты. Если в списке ничего похожего нет, попробуй выгрузить таблицу методов и поискать в ней PEG:
sudo cat /sys/firmware/acpi/tables | strings | grep -i -E 'SWRT|PEG0'
Метод слетает при каждом suspend, поэтому включение удобнее оформить как systemd-скрипт сна:
# /usr/lib/systemd/system-sleep/acpi-nvidia
#!/bin/sh
case "$1" in
post|resume) echo 1 > /sys/firmware/acpi/calls/_SB._SB.PCI0.PEG0.SWRT.DSTS ;;
esac
Тот же приём с аргументом 0 в секции pre|post возвращает карту к жизни.
Сам драйвер умеет ограничивать себя. Ниже — энергопотребление в простое, где карта сама просит мало, а вот в играх пригодится ограничение по ваттам:
sudo nvidia-smi -pl 60
nvidia-smi -pl 100
Ограничение мощности упирается в запрос карты и помогает сильнее, чем снижение частот. Про частоты, turbo и limits — отдельный разбор про перегрев, вентиляторы и Coolbits.
Для замера эффекта помогает powertop — он показывает, какие устройства просыпаются и сколько съедают:
sudo powertop --auto-tune
Осторожно: --auto-tune любит усыплять dGPU и конфликтует с ручным переключением через Prime. Сначала настрой модуль вручную, потом включай powertop, и следи, чтобы вернуть карту из сна. Для замера потребления удобнее periodic-строка в nvidia-smi.
Отдельная история с батареей — заряд до 100% каждый день ускоренно её изнашивает. На ThinkPad порог задаётся прямо в sysfs:
cat /sys/class/power_supply/BAT0/charge_control_end_threshold
echo 80 | sudo tee /sys/class/power_supply/BAT0/charge_control_end_threshold
Да, если карта всё равно уходит в D3cold — с выключенным persistence mode драйвер не держит карту инициализированной. Но просыпается она дольше, первая игра даст пару секунд задержки. Для работы в поезде экономия обычно важнее.
Потому что команда обращается к драйверу, а тот поднимает устройство. Это ожидаемое поведение: сам факт вызова разбудит GPU. Для контроля смотри power_state в sysfs, а не nvidia-smi.
Разные задачи. prime-run разово отправляет один процесс на NVIDIA, prime-select меняет поведение системы в целом и требует ручного переключения обратно, иначе драйвер уедет в D0 надолго.
Сама по себе нет. Сброс состояния D3cold добавляет задержку старта приложения — от долей секунды до пары секунд. В играх карта всё равно сразу уходит в P0, где потребление максимальное.
Пройди по порядку: отключи внешний монитор и проверь power_state снова, сними nouveau через blacklist и пересобери initramfs, включи NVreg_DynamicPowerManagement=0x02, отключи persistence mode. Если после этого D0 остаётся, у ноутбука почти наверняка MUX без раздельного питания, и путь один — режим «только встроенная графика» в BIOS. А вот ограничение мощности (nvidia-smi -pl) экономии батареи почти не даёт: карта в простое и так просит мало, а лимит упирается в артефакты в играх. Держи его повыше.
Начни с NVreg_DynamicPowerManagement=0x02 и nvidia_drm.fbdev=1 — это дешёвые правки, которые дают основную часть экономии. Если карта всё равно просыпается, добавь acpi_call с методом SWRT.DSTS или переключись в BIOS на «только встроенную графику». На ноутбуках с NVIDIA Optimus проблему удобнее решить аппаратно: MUX переключается из ОС, и dGPU действительно обесточивается.
Задай вопрос в чате — отвечаем быстро, по делу и без воды.
Комментарии