Nvidia Optimus on Linux
November 23, 2019 · 5 mins to read
If you’re using any distribution of Linux on your laptop with Nvidia GPU you know that Nvidia drivers are problematic. Why? There are several reasons:
- Nvidia drivers are proprietary, which means their code is closed, and only Nvidia can release updates. So the community cannot do anything except wait until Nvidia decides to implement or fix something. There are open-source drivers, however, their performance is significantly worse than the proprietary ones.
- Until recently there was no support for Nvidia Optimus which allows using your integrated video-card for casual applications and GPU for games and other GPU-heavy processes. This problem is semi-solved with PRIME which is the best case requires to log out and log in back.
- Nvidia GPU consumes a lot of power when it’s not used. So there is no way to turn it off when it’s not used.
But now, the problem #2 and #3 is solved in drivers 435.xx by adding support for PRIME Render Offloading which allows rendering GPU heavy applications on GPU and others on the integrated. Also, the drivers introduced support for D3 Power Managment which makes GPU not consume power when it’s not used.
I tried to install those new drivers and see whether it’s working, and it DID WORK!
Unfortunately, there are few big and important requirements to make D3 power management to work:
- Turing-generation GPU. Those are GPUs starting from GTX 1650, see the link for more details.
- Intel 8th generation Coffee Lake processor
If your laptop (or PC) meets the requirements you can enable D3 power management mode, otherwise, you only can enable Nvidia Offloading which without D3 is not that useful on laptops as Nvidia GPUs consumes a lot of power and drain the battery very fast.
I tried to do this on my Dell XPS 15 7590 with GeForce GTX 1650 and Intel(R) Core(TM) i7-9750H. I’m running Manjaro Linux as my distro so the instruction bellow will use Manjaro specific tools.. For Ubuntu/Debian you probably can use apt
with appropriate package names.
Let’s start!
-
Follow Nvidia driver’s instructions and remove built-in drivers and install driver 435xx or newer. In Manjaro you can do:
sudo mhwd -i pci video-nvidia-435xx
-
After installation, reboot or logout to apply new changes, whatever works for you. If you correctly installed the drivers you should be able to see output for
nvidia-smi
command. Which looks like something like this:$ nvidia-smi Sat Nov 23 14:47:49 2019 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 440.31 Driver Version: 440.31 CUDA Version: 10.2 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GeForce GTX 1650 Off | 00000000:01:00.0 Off | N/A | | N/A 44C P8 14W / N/A | 38MiB / 3914MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 17281 G /usr/lib/Xorg 37MiB | +-----------------------------------------------------------------------------+ ```
-
The next step is to enable GPU offloading. You can do it by performing these official instructions from Nvidia. For Majaor, you can install optimus-manager and set
hybrid
mode (ignore the warning for now).sudo pacman -S optimus-manager optimus-manager --switch hybrid
-
(Optinal) Currently, no stable version of X.org or Wayland supports GPU offloading. However, for X.org, if you want it to run on GPU you can install the patched by Nvidia engineer X.org. For Manjaro just clone the repo, build, and install the package. After the installation log out and log in back to restart X.org server:
cd "$(mktemp -d)" git clone https://gitlab.freedesktop.org/aplattner/arch-xorg-servercd arch-xorg-server makepkg -s sudo pacman -U *.xz
-
Enable D3 Power Mode so your Nvidia GPU is turned off when not used by following guide from Nvidia (use Automated Setup). Reboot to apply the changes.
If you everything did correct, you should be able to offload processes to GPU by setting the following environment variables:
__NV_PRIME_RENDER_OFFLOAD=1
for Vulkan apps__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia
for OpenGL apps.
I created an prime
alias and saved in .bashrc
for settings those variables. To do it add this line to your .bashrc
or .bash_profile
or whatever shell config you’re using:
alias prime='__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia'
And to verify it works try the following:
# mikael @ mikael-pc in /tmp/tmp.NNYn0gkreU [14:38:37]
$ prime glxinfo | grep -i "opengl renderer"OpenGL renderer string: GeForce GTX 1650/PCIe/SSE2
# mikael @ mikael-pc in /tmp/tmp.NNYn0gkreU [14:38:40]
$ glxinfo | grep -i "opengl renderer" OpenGL renderer string: Mesa DRI Intel(R) UHD Graphics 630 (Coffeelake 3x8 GT2)
As you can see, when I append prime
the process uses Nvidia GPU and if I don’t it uses Intel GPU.
To offload games in Steam to your GPU add those environment variables to your game launch options. If your game uses Vulkan API you can do:
__NV_PRIME_RENDER_OFFLOAD=1 %command%
I hope this guide helped you to setup GPU Offloading and D3 power management state. If you have questions write in the comments, I’ll try to answer then.
Thanks for reading!