PRIME
PRIME 是一种用于管理最新一些台式机和笔记本电脑上的混合图形的技术(NVIDIA 的 Optimus,Radeon 的 AMD 动态可切换图形)。PRIME GPU 分载(offloading)和反向 PRIME(reverse PRIME)是在 Linux 内核中支持无复用混合显示的尝试。
- 本文出现的一些不常用缩写的解释:
- iGPU - integrated GPU,集成显卡
- dGPU - discrete/dedicated GPU,独立/专用显卡
用户希望在更强大的显卡上渲染应用程序,并将结果发送到连接显示器的显卡。
命令 xrandr --setprovideroffloadsink provider sink 可用于让渲染分载提供程序(offload provider)将其输出发送到接收端(sink)提供程序(也就是连接了显示器的提供程序)。提供程序和接收端标识符可以是数字(0x7d、0x56)或区分大小写的名称(Intel、radeon)。
xf86-video-* 或内置内核级显示模式设置)驱动程序时,不再需要此设置,因为它们默认启用 DRI3,因此会自动地这样设置。不过,再次显式设置它们一次也不会有什么害处。样例:
$ xrandr --setprovideroffloadsink radeon Intel
命令中的提供程序也可以用序号代替名字:
$ xrandr --setprovideroffloadsink 1 0
要将独立显卡用于最需要它的应用程序(例如游戏、3D 建模器...),请在程序的启动命令前面加上环境变量 DRI_PRIME=1:
$ DRI_PRIME=1 glxinfo | grep "OpenGL renderer"
OpenGL renderer string: Gallium 0.4 on AMD TURKS
/sys/bus/pci/devices/,但前缀为 pci- 并将分号和点替换为下划线,例如 DRI_PRIME=pci-0000_01_00_0。其他应用程序仍将使用功耗较低的集成显卡。一旦 X 服务器重新启动,这些设置就会丢失,可能需要制作一个脚本并在桌面环境启动时自动运行(或者将其放在 /etc/X11/xinit/xinitrc.d/ 目录下面)。不过,这样可能会缩短电池寿命并增加热量。
更多信息可以参考 Gentoo:AMDGPU#Identifying which graphics card is in use。
为了让 DRI_PRIME 在 Vulkan 应用程序上工作,需要安装 vulkan-mesa-layers包,以及用于 32 位应用程序的 lib32-vulkan-mesa-layers包。
NVIDIA 驱动程序从版本 435.17 开始支持这个方案。iGPU 驱动程序 xf86-video-amdgpu包(450.57)和 xf86-video-intel包(455.38)官方支持内核级显示模式设置(modesetting)。
要在 NVIDIA 显卡上运行程序,您可以使用 nvidia-prime包 软件包提供的 prime-run 脚本:
$ prime-run glxinfo | grep "OpenGL renderer" $ prime-run vulkaninfo
在 GPU 不和 PRIME 分载或反向 PRIME 一起使用的时候,内核 PCI 电源管理就会关闭该 GPU。
内核级显示模式设置、xf86-video-amdgpu包、xf86-video-intel包、xf86-video-nouveau包 驱动程序都支持此功能。
以下命令可用于检查每个 GPU 当前的电源状态:
$ cat /sys/class/drm/card*/device/power_state
对于在 Intel Coffee Lake 或更高版本 CPU 以及某些 Ryzen CPU(如 5800H)平台上运行的图灵(Turning)架构显卡,可以在不使用的时候完全关闭 GPU。
需要以下 udev 规则,如 NVIDIA 所建议的:
/etc/udev/rules.d/80-nvidia-pm.rules
# Enable runtime PM for NVIDIA VGA/3D controller devices on driver bind
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="auto"
# Disable runtime PM for NVIDIA VGA/3D controller devices on driver unbind
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="on"
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="on"
一些用户还报告以下附加行也是必要的:
/etc/udev/rules.d/80-nvidia-pm.rules
# Enable runtime PM for NVIDIA VGA/3D controller devices on adding device
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="auto"
同时设置以下模块参数:
/etc/modprobe.d/nvidia-pm.conf
options nvidia "NVreg_DynamicPowerManagement=0x02"
此外,您可以安装 nvidia-prime-rtd3pmAUR,它提供了这两个配置文件。
在设置好 udev 规则和模块参数 后,您需要重新启动笔记本电脑。
要检查 NVIDIA GPU 是否已关闭,可以使用以下命令:
$ cat /sys/bus/pci/devices/0000:01:00.0/power/runtime_status
您将看到 suspended 或 running。如果显示 suspended,则 GPU 已关闭,现在功耗将为 0 瓦,从而延长电池寿命。
在某些情况下,例如 NVIDIA RTX A1000,可能不会列出上述任何选项,而是显示 active。这并不一定意味着 GPU 处于 running 状态。在这种情况下,您可以使用以下命令检查状态:
$ cat /sys/bus/pci/devices/0000:01:00.0/power/runtime_suspended_time
当 GPU 处于 suspended 状态时,每次运行该命令时计数器都会递增。当 GPU 的状态变为 running 时,它将停止递增。
如果您注意到 runtime_suspended_time 没有递增,您可以使用以下命令检查您的 D3 状态。
$ cat /proc/driver/nvidia/gpus/0000:01:00.0/power
如果它显示 Runtime D3 status: Not supported,您可能需要按照 此论坛帖子 中的步骤禁用它。一位用户指出禁用 GpuFirmware 仅适用于闭源驱动程序,不适用于 nvidia-open包。
还需要启用 nvidia-persistenced.service 服务以避免内核在 NVIDIA 设备资源不再使用时清空设备状态[3]。
即使没有启用动态电源管理,应用程序的渲染分载也要启用[4]。
要在动态电源管理启用时将应用程序分载到 NVIDIA GPU,需添加以下环境变量:[5]
__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia command
在 Steam 游戏上使用时, 启动命令行选项可以设置为:
__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia %command%
__NV_PRIME_RENDER_OFFLOAD 的值可能需要根据系统设置为 0。建议检查哪个 GPU 是 0,哪个是 1,因为此变量指定将使用哪个 GPU。安装 switcheroo-control包 并启用 switcheroo-control.service 以使用 GNOME 集成。
GNOME 尊重桌面项中的 PrefersNonDefaultGPU 属性。或者也可以通过右键单击图标并选择 Launch using Discrete Graphics Card 来使用 GPU 启动应用程序。
When running Windows DirectX games under Wine or Proton, you need to instruct DXVK directly using:
DXVK_FILTER_DEVICE_NAME "[your preferred card name]"
Get the card name from vulkaninfo; DXVK uses substring match.
如果安装了 bumblebee包,则需要将其删除,因为它将 nvida_drm 列入黑名单,该驱动程序由 X 服务器加载 NVIDIA 驱动程序来实现渲染分载。
当使用 PRIME 时,主 GPU 渲染屏幕内容/应用程序,并将其传递给备用 GPU 进行显示。参考an NVIDIA thread 此帖,"传统的 vsync 可以将应用程序的呈现与系统内存中的副本同步,但需要一种额外的机制来将系统内存中的副本与 iGPU 的显示引擎同步。与传统的垂直同步不同,这种机制必须涉及到 dGPU 和 iGPU 驱动之间的通信。"
这种同步是使用 PRIME 同步实现的。要检查显示系统是否启用了 PRIME 同步,可以查看 xrandr --prop 的输出。
使用下面的命令启用(PRIME 同步):
$ xrandr --output <output-name> --set "PRIME Synchronization" 1
- 在 NVIDIA 驱动程序上使用 PRIME 同步的先决条件是启用 NVIDIA#DRM 内核级显示模式设置。
- PRIME 同步无法在 AMDGPU DDX 驱动上使用(xf86-video-amdgpu包)。
如果第二个 GPU 的输出无法被主 GPU 访问,可以使用反向 PRIME来使用它们。这将涉及使用主 GPU 渲染图像,然后将它们传递给第二个 GPU。
它可能开箱即用,但如果不能,则需要按照以下步骤进行配置。
首先, 识别集成显卡的总线 ID(BusID)
lspci -d ::03xx
00:02.0 VGA compatible controller: Intel Corporation UHD Graphics 630 (Mobile) 01:00.0 VGA compatible controller: NVIDIA Corporation TU117M [GeForce GTX 1650 Mobile / Max-Q] (rev a1)
在上面的示例中,Intel 集成显卡的总线 ID 是 00:02.0 ,翻译到 pci 总线上为 PCI:0:2:0。
如下设置您的 xorg.conf 并调整总线 ID。
/etc/X11/xorg.conf
Section "ServerLayout"
Identifier "layout"
Screen 0 "intel"
Inactive "nvidia"
Option "AllowNVIDIAGPUScreens"
EndSection
Section "Device"
Identifier "nvidia"
Driver "nvidia"
EndSection
Section "Screen"
Identifier "nvidia"
Device "nvidia"
EndSection
Section "Device"
Identifier "intel"
Driver "modesetting"
BusID "PCI:0:2:0"
EndSection
Section "Screen"
Identifier "intel"
Device "intel"
EndSection
命令 xrandr --setprovideroutputsource provider source 将提供程序设置为源输出。 例如:
$ xrandr --setprovideroutputsource radeon Intel
完成后,独立显卡的输出应该在 xrandr 中可用,可以执行以下操作来配置内部和外部显示器:
$ xrandr --output HDMI-1 --auto --above LVDS1
如果重启后你只有一个提供程序,可能是因为当 Xorg 启动时nvidia模块还没加载。您需要启用早期模块加载。 有关详细信息,请参阅NVIDIA#早启动。
删除或者移走 /etc/X11/xorg.conf 以及 /etc/X11/xorg.conf.d/ 目录下任何与 GPU 有关的文件
某些情况下 PRIME 的正常工作需要一个混合窗口管理器。如果你的窗口管理器不进行混合渲染,你可以在其基础上使用 混合窗口管理器。
如果你使用 Xfce,你可以进入菜单 > 设置 > 窗口管理器调整 > 混合器并启用混合渲染,然后再次尝试你的应用程序。
目前基于 GL 的渲染合成器和 PRIME 分载渲染还有一些问题。当基于 Xrender 的渲染合成器(xcompmgr、xfwm、compton的默认后端,cairo-compmgr 和一些其他的合成器)可以正常工作,基于 GL 的渲染合成器(Mutter/muffin、Compiz、使用 GLX 后端的 compton、Kwin 的 OpenGL 后端等)一开始会显示黑屏,就好像没有运行渲染合成器一样。虽然也可以通过调整使用渲染分载的程序窗口大小来强制显示图像,但这并不是一个实用的解决方案,因为它不适用于全屏的 Wine 应用程序。这意味着像 GNOME3 和 Cinnamon 这样的桌面环境在使用 PRIME 分载时存在问题。
此外,如果使用的是英特尔 IGP,也许可以通过把 IGP 当作 UXA 而不是 SNA 运行来修复 GL合成问题,然而这可能会导致渲染分载进程出现问题(例如,xrandr --listproviders 可能不会打印独立 GPU)。
如果你启用了 RTD3(来自#NVIDIA),在使用 Wayland 时,程序打开时会感到一些延迟,这是因为它会先尝试启动 GPU(这需要大约1秒或更长时间),然后才尝试打开程序,浪费了时间和电池寿命。这是 NVIDIA 驱动的问题。更多细节参见此帖。
欲解决该问题,请在您的 /etc/environment文件中添加以下两行:
/etc/environment
__EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json __GLX_VENDOR_LIBRARY_NAME=mesa
当使用 PRIME 分载时,遇到 Major opcode of failed request: 156 (NV-GLX) 是一个已知问题。目前唯一的解决方法是启动X会话时完全使用 NVIDIA GPU。一个用户友好的方式是在 NVIDIA 独显和PRIME分载方法之间切换是使用 optimus-manager 工具或自己编写一些自动化脚本。