Windows hybrid GPU management
Nvidia hybrid gpu setups in linux are incredibly painful due to poor driver support, nvidia drivers don’t properly support being run as a secondary gpu, I could go on and on about this…
It seems that windows is not immune to hybrid gpu pains. I recently discovered failures in Windows 11 23H2 switching from dGPU to iGPU on my Lenovo P1 Gen 5 (intel Xe / nv 3070Ti).
Behaviour
This machine is configured in a very common way, iGPU and dGPU are connected to the internal screen through a multiplexer, HDMI and USB-C ports are wired directly to the Nvidia GPU.
This means that the dGPU must be active to use external displays, but can be powered down for a portable configuration. The fact that the gpu can power down is really useful as even idle the gpu draws ~15w.
Typical behaviour in Windows for hybrid GPU setups is that the “High performance” gpu will be powered if either:
- A high-performance application is running, i.e. game
- An external display is plugged in
My experience has been that the dGPU doesn’t actually power down when the external display is disconnected, resulting in terrible battery life after unplugging my machine from displays.
Based on information from Nvidia control panels “gpu activity icon” I have been able to deduce that the dGPU isn’t powering down because there are applications running on it. To me this shows that it’s a windows issue, surprise surprise…
Monitoring
Open the Nvidia control panel - Desktop -> Display GPU Activity Icon in notification area.
Solution
Disable and re-enable the nvidia dGPU when you undock.
The battery.ps1
powershell script disables the nvidia GPU and re-enables it which effectively kicks all processes running on the dGPU off. Be warned that this may unsafely kill any applications you are using that depend on the dGPU, but i’ve had no issues with things like browsers etc, ymmv.
battery.ps1
Get-PnpDevice -Class "Display" | Where-Object Manufacturer -eq "NVIDIA" | Disable-PnpDevice -Confirm:$false
Get-PnpDevice -Class "Display" | Where-Object Manufacturer -eq "NVIDIA" | Enable-PnpDevice -Confirm:$false
I used this command prompt convenience script to call the PS script manually, but for long term use you probably want to automate this based on power events or display PNP events.
battery.cmd
powershell -ExecutionPolicy Bypass -File c:\Users\jake\Desktop\battery.ps1
Result
‘convincing’ the dGPU to turn off changes this machine from having 1.5h battery life, to 3-4h (usage dependant), which I consider a massive win. Even if I am forced to run windows.