Hybrid graphics (Português)
Gráficos híbridos é um conceito que envolve duas placas gráficas no mesmo computador. Dispositivos com duas GPUs diferentes, frequentemente laptops, em geral possuem:
- um Processador Gráfico Dedicado/Discreto, que oferece uma maior performance, mas aumenta o consumo energético do dispositivo;
- um Processador Gráfico Integrado, que em geral requer muito menos energia, mas cuja performance é suficiente apenas para a renderização de aplicativos não graficamente intensivos, como navegadores e o ambiente desktop.
Portanto, surge naturalmente a necessidade de uma tecnologia que otimize ambos os usos. Com base nisso, as fabricantes de laptops, individualmente, desevolveram suas próprias tecnologias de gráficos híbridos que permitem manter a GPU dedicada em um estado "dormente" até que sua performance em renderização 3D seja requisitada em comparação à GPU integrada.
Existe uma variedade de implementações que resolvem esta questão. A tecnologia de gráficos híbridos é bem suportada no Windows, mas ainda é meio rudimentar em distribuições Linux. Este artigo tentará explicar um pouco sobre a cada abordagem e descrever algumas soluções da comunidade quanto à falta de suporte GNU/Linux das fabricantes.
Alternância dinâmica
A grande maioria das novas tecnologias de gráficos híbridos envolvem duas placas gráficas: as placas dedicada e integrada são acopladas a um framebuffer e não há um multiplexador em hardware. A placa integrada está sempre ligada e a dedicada é ligada/desligada dependendo da necessidade de performance ou poupagem de energia, respectivamente. Na maior parte dos casos, não há nenhuma maneira de utilizar apenas a placa dedicada, e a alternância e a renderização são controladas por software. Durante a inicialização, o kernel Linux passa a usar um modo de vídeo e a organizar os drivers gráficos de baixo nível a serem usados pelos aplicativos. A maior parte das distribuições Linux usam então o X.org para criar um ambiente gráfico. Finalmente, alguns outros programas são executados; primeiro um gerenciador de login, depois um gerenciador de janelas, e assim por diante. Esse sistema hierárquico foi desenhado para ser usado, na maior parte das vezes, sob uma única placa gráfica.
Desligar totalmente a GPU discreta
Você pode ter interesse em desligar o processador gráfico de alta performance para poupar bateria.
Usando o BIOS/UEFI
Algumas fabricantes de laptops providenciam uma opção no BIOS ou UEFI para desativar completamente a GPU dedicada.
Usando regras udev
Tenha certeza de que quaisquer configurações do seu gerenciador de display para NVIDIA estejam removidas.
Ponha os drivers nouveau na lista negra criando
/etc/modprobe.d/blacklist-nouveau.conf
blacklist nouveau options nouveau modeset=0
E então, crie
/etc/udev/rules.d/00-remove-nvidia.rules
# Remove dispositivos NVIDIA USB xHCI Host Controller, se presentes
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c0330", ATTR{power/control}="auto", ATTR{remove}="1"
# Remove dispositivos NVIDIA USB Type-C UCSI, se presentes
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c8000", ATTR{power/control}="auto", ATTR{remove}="1"
# Remove dispositivos NVIDIA Audio, se presentes
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x040300", ATTR{power/control}="auto", ATTR{remove}="1"
# Remove dispositivos NVIDIA VGA/3D controller
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x03[0-9]*", ATTR{power/control}="auto", ATTR{remove}="1"
Dê reboot no sistema e execute lspci para ver se a sua GPU NVIDIA ainda está listada.
Verifique o consumo energético para ter certeza de que sua GPU não está usando energia. Se estiver, #Usando acpi_call pode ser uma outra opção para desativá-la completamente.
Usando bbswitch
Com uma GPU da NVIDIA, isso pode ser feito de forma mais segura com o bbswitch, que consiste em um pacote kernel que automaticamente envia as chamadas ACPI corretas para desativar a GPU discreta quando não requisitada, ou automaticamente durante a inicialização do sistema.
bbswitch não funciona com o método de gerenciamento de consumo pela porta PCIe desde o kernel 4.8. Veja Bumblebee#Broken power management with kernel 4.8 para mais detalhes.Usando acpi_call
Caso não dê certo, e também para as GPUs não suportadas pelo bbswitch, o mesmo pode ser feito instalando manualmente o pacote acpi_call.
Uma vez instalado, carregue o módulo de kernel:
# modprobe acpi_call
Com o módulo de kernel carregado, execute o script em /usr/share/acpi_call/examples/turn_off_gpu.sh.
O script vai passar por todos os barramentos de dados (data buses) conhecidos, tentando desligá-los. Você vai receber uma saída similar a esta:
# /usr/share/acpi_call/examples/turn_off_gpu.sh
Trying \_SB.PCI0.P0P1.VGA._OFF: failed Trying \_SB.PCI0.P0P2.VGA._OFF: failed Trying \_SB_.PCI0.OVGA.ATPX: failed Trying \_SB_.PCI0.OVGA.XTPX: failed Trying \_SB.PCI0.P0P3.PEGP._OFF: failed Trying \_SB.PCI0.P0P2.PEGP._OFF: failed Trying \_SB.PCI0.P0P1.PEGP._OFF: failed Trying \_SB.PCI0.MXR0.MXM0._OFF: failed Trying \_SB.PCI0.PEG1.GFX0._OFF: failed Trying \_SB.PCI0.PEG0.GFX0.DOFF: failed Trying \_SB.PCI0.PEG1.GFX0.DOFF: failed Trying \_SB.PCI0.PEG0.PEGP._OFF: works! Trying \_SB.PCI0.XVR0.Z01I.DGOF: failed Trying \_SB.PCI0.PEGR.GFX0._OFF: failed Trying \_SB.PCI0.PEG.VID._OFF: failed Trying \_SB.PCI0.PEG0.VID._OFF: failed Trying \_SB.PCI0.P0P2.DGPU._OFF: failed Trying \_SB.PCI0.P0P4.DGPU.DOFF: failed Trying \_SB.PCI0.IXVE.IGPU.DGOF: failed Trying \_SB.PCI0.RP00.VGA._PS3: failed Trying \_SB.PCI0.RP00.VGA.P3MO: failed Trying \_SB.PCI0.GFX0.DSM._T_0: failed Trying \_SB.PCI0.LPC.EC.PUBS._OFF: failed Trying \_SB.PCI0.P0P2.NVID._OFF: failed Trying \_SB.PCI0.P0P2.VGA.PX02: failed Trying \_SB_.PCI0.PEGP.DGFX._OFF: failed Trying \_SB_.PCI0.VGA.PX02: failed
Viu o "works"? Isso significa que o script encontrou um barramento em que a sua GPU está conectada, e através dela conseguiu desligar a placa. Como uma forma de confirmar, veja se seu tempo de bateria restante aumentou.
Desligando a GPU automaticamente
Do jeito que as coisas estão, a placa gráfica vai ser ligada novamente na próxima reinicialização. Para começar a resolver isso, carregue o módulo de kernel durante a inicialização:
/etc/modules-load.d/acpi_call.conf
# Carrega 'acpi_call.ko' durante a inicialização. acpi_call
Durante a inicialização
Para desligar a GPU no iniciar do sistema, é possível usar os systemd-tmpfiles.
/etc/tmpfiles.d/acpi_call.conf
w /proc/acpi/call - - - - \\_SB.PCI0.PEG0.PEGP._OFF
A configuração acima será carregada durante a inicialização pelo systemd. O que ela faz é escrever o específico sinal OFF ao arquivo /proc/acpi/call. Obviamente, troque \_SB.PCI0.PEG0.PEGP._OFF pelo barramento que funciona no seu sistema (note que a contrabarra deve ser escapada).
Após a inicialização do servidor X
Em alguns sistemas, desligar a GPU discreta antes que o servidor X possa ser inicializado pode travar o sistema. Nesses casos, pode ser melhor desligar a GPU após a inicialização do servidor X, que é possível com alguns gerenciadores de display. No LightDM, por exemplo, o parâmetro de configuração display-setup-script pode ser usado para executar um script com privilégios de raiz que desative a GPU. Se você usa o SDDM, então você pode adicionar a linha echo "\_SB.PCI0.PEG0.PEGP._OFF" > /proc/acpi/call tanto para o arquivo /usr/share/sddm/scripts/wayland-session quanto para /usr/share/sddm/scripts/Xsession, dependendo se você usa o Wayland ou o Xorg. Lembre-se de trocar \_SB.PCI0.PEG0.PEGP._OFF pelo que funciona no seu sistema!
System76
Alguns laptops da System76 (como o Oryx Pro) possuem sua própria opção de gráficos híbridos. Para fazer uso dela, instale system76-powerAUR, ative o serviço system76-power.service, e execute system76-power graphics hybrid.
Desligar totalmente a GPU discreta
Primeiro, tenha certeza de que você está usando o modo de gráficos integrados executando system76-power graphics integrated e dando reboot. Uma vez no modo integrado, execute system76-power graphics power off para desligar a GPU discreta. Esse comando não é persistente, e precisará ser executado após cada inicialização.
Solução de problemas
O tempo de início de certos aplicativos é defasado por 30 segundos
Quando invocado, o Vulkan tenta inicializar o Installable Client Driver (ICD) especificado em /usr/share/vulkan/icd.d/nvidia_icd.json. O pacote nvidia-utils configura esse arquivo para referir ao driver libGLX_nvidia, dando ao Vulkan informação quanto ao caminho do driver da GPU. Entretanto, se a GPU está desativada, a inicialização desse driver irá falhar, fazendo com que certos aplicativos (e.g., aqueles baseados no Chromium/Electron) tenham seu início pausado até que um timeout de 30 segundos seja alcançado. Para prevenir o Vulkan de tentar carregar o driver em primeiro, e então mitigar este timeout, você pode redefinir a localização do arquivo JSON do ICD usando a variável de ambiente VK_DRIVER_FILES. Para indefiní-la, use:
$ export VK_DRIVER_FILES=
Alto consumo energético mesmo após desativando a GPU discreta da NVIDIA
Se após desativar a GPU dedicada (em #Usando acpi_call) o consumo energético ainda está alto, veja se o módulo de kernel nouveau está carregado com lsmod. Se não estiver, então assegure-se de que ele esteja instalado, que quaisquer entradas nos arquivos .conf que ponham o Nouveau na lista negra em /etc/modprobe.d/ foram removidas, e que o módulo de kernel Nouveau esteja sendo carregado automaticamente durante a inicialização. Depois de um reboot, o consumo energético deve ser menor.
/sys/class/backlight, adicione a linha acpi_backlight=native aos seus parâmetros de kernel.