跳转至内容

PRIME

来自 ArchWiki

PRIME 是一项用于管理现代台式机和笔记本电脑中混合显卡的技术(NVIDIA Optimus,Radeon 的 AMD 动态可切换显卡)。PRIME GPU 卸载反向 PRIME 是 Linux 内核中用于支持 muxless 混合显卡的技术方案。

PRIME GPU 卸载

我们的目的是在性能更强的显卡上渲染应用程序,并将结果发送到连接了显示器的显卡上。

可以使用命令 xrandr --setprovideroffloadsink provider sink 来让渲染卸载提供程序将其输出发送到接收端(即连接了显示器的提供程序)。提供程序和接收端的标识符可以是数字 (0x7d, 0x56) 或区分大小写的名称 (Intel, radeon)。

注意 使用官方仓库中大多数默认的 Xorg DDX(xf86-video-* 或内置的 modesetting)驱动程序时,此设置不再必要,因为它们默认启用了 DRI3,因此会自动进行这些分配。不过,再次显式设置它们也不会造成负面影响。

示例

$ xrandr --setprovideroffloadsink radeon Intel

你也可以使用提供程序索引而不是提供程序名称。

$ xrandr --setprovideroffloadsink 1 0

本文或本节需要在语言、wiki 语法或风格方面进行改进。请参阅 Help:Style 获取参考。

原因: 以下子章节较为混乱,我们将一个子章节命名为 PRIME 渲染卸载,但未说明它是以 NVIDIA 为中心的;我们将针对开源驱动的通用 PCI-E 电源管理混入其中。一旦此处清理完毕并可以链接至此处以获取所需的环境变量,应将 External GPU#Xorg rendered on iGPU, PRIME render offload to eGPU 中的合并标志在此解决。(在 Talk:PRIME 中讨论)

用于开源驱动—PRIME

若要将独立显卡用于最需要的应用程序(例如游戏、3D 建模软件等),请在命令前添加 DRI_PRIME=1 环境变量。

$ DRI_PRIME=1 glxinfo | grep "OpenGL renderer"
OpenGL renderer string: Gallium 0.4 on AMD TURKS
  • 除了数值,你也可以指定 PCI 设备名称。格式类似于 /sys/bus/pci/devices/,但需以 pci- 为前缀,并将分号和点替换为下划线,例如 DRI_PRIME=pci-0000_01_00_0。你可以通过 lspci -nnd ::03xx 列出按 PCIe ID 分类的图形设备。
  • 对于 Vulkan 渲染,你可以添加 ! 以仅将所选 GPU 暴露给应用程序,例如 DRI_PRIME=1!

其他应用程序仍将使用功耗较低的集成显卡。这些设置在 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

关于 Windows 游戏的说明

本文或本章节是与 DXVK 合并的候选对象。

说明: 游戏并不是本页面的主要议题。(在 Talk:PRIME 中讨论)

在 Wine 或 Proton 下运行 Windows DirectX 游戏时,你需要使用环境变量直接指示 DXVK

DXVK_FILTER_DEVICE_NAME="[your preferred card name]"

通过 vulkaninfo 获取显卡名称;DXVK 使用子字符串匹配。

PRIME 渲染卸载

NVIDIA 驱动程序自 435.17 版本起支持此方法。官方支持的 iGPU 驱动程序包括 modesetting、xf86-video-amdgpu (450.57) 和 xf86-video-intel (455.38)。

若要在 NVIDIA 显卡上运行程序,可以使用 nvidia-prime 提供的 prime-run 脚本。

$ prime-run glxinfo | grep "OpenGL renderer"
$ prime-run vulkaninfo

PCI-Express 运行时 D3 (RTD3) 电源管理

开源驱动

内核 PCI 电源管理会在不使用 PRIME 卸载或反向 PRIME 时关闭 GPU。此功能由 modesetting、xf86-video-amdgpuxf86-video-intelxf86-video-nouveau 驱动程序支持。

可以使用以下命令检查每个 GPU 的当前 [1] 电源状态:

$ cat /sys/class/drm/card*/device/power_state
NVIDIA
  • 对于 Ampere 架构显卡,通常无需配置,因为此功能默认开启。对于部分 Ampere 用户,可能需要 udev 规则。
  • 一些使用混合显卡的用户报告称,在升级到较新的 NVIDIA 驱动程序(似乎 >525)后,其独立 NVIDIA Ampere GPU 无法保持在 D3Cold 电源状态 [2]
  • 一些使用 Ampere 之前显卡且在较新驱动上 D3 支持损坏的用户报告了一种变通方法:通过 NVreg_EnableGpuFirmware=0 禁用 GSP 固件 [3]

对于使用 Intel Coffee Lake 或更高版本 CPU 以及部分 Ryzen CPU(如 5800H)的 Turing 架构显卡,可以实现 在不使用时完全关闭 GPU 电源

注意 如果你计划使用挂起或休眠,请参阅 NVIDIA/Tips and tricks#Preserve video memory after suspend

需要根据 NVIDIA 的建议添加以下 udev 规则:

/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"
注意 对于支持该配置的 Ampere 或更新的笔记本电脑,需要使用 NVreg_DynamicPowerManagement=0x03

或者,你可以安装 nvidia-prime-rtd3pmAUR,它提供了这两个配置文件。

手动或使用 AUR 包设置好 udev 规则和 模块参数后,你需要重启笔记本电脑。

要检查 NVIDIA GPU 是否已关闭,可以使用此命令:

$ cat /sys/bus/pci/devices/0000:01:00.0/power/runtime_status

你将看到 suspendedrunning。如果显示 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

  • nvidia-open 用户:请升级到 610 或更高版本的驱动程序,在该版本中,运行时 D3 电源管理已 默认获得完全支持。(在较早版本的开源驱动上,即便是下方的变通方法也 无效。)
  • 闭源驱动用户:你可能需要按照 此论坛帖子 中的步骤禁用 GSP 固件。

要检查是什么在使用 GPU,可以使用以下命令:

# lsof +c0 /dev/nvidia*

与 nvidia-smi 不同,它会报告每个使用该设备的进程,并且不会唤醒 GPU。

我们还需要 启用 nvidia-persistenced.service,以避免在 NVIDIA 设备资源不再使用时,内核强制拆除设备状态。[4]

配置应用程序使用 GPU 渲染

本文或本章节是与 External GPU#Xorg rendered on iGPU, PRIME render offload to eGPU 合并的候选对象。

说明: 目标章节提到了这些变量。或许可以将其与目标章节合并以避免重复?(在 Talk:PRIME 中讨论)

即使未启用动态电源管理,也需要对应用程序进行渲染卸载 [5]

要在启用动态电源管理的情况下运行卸载到 NVIDIA GPU 的应用程序,请添加以下 环境变量[6]

__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia command

Steam 游戏上使用时,启动项命令行可以设置为:

__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia %command%

桌面环境集成

安装 switcheroo-control启用 switcheroo-control.service

GNOME、KDE Plasma、Cinnamon、COSMIC 和 Budgie 桌面环境将遵循 桌面入口文件 中的 PrefersNonDefaultGPU 属性,并自动在指定的 GPU 上启动应用程序。

此外,在 GNOME、Cinnamon 和 COSMIC 上,你可以通过右键点击图标并分别选择 使用独立显卡启动 (GNOME)、使用专用 GPU 运行 (Cinnamon) 和 使用 (GPU 名称) 运行 (COSMIC) 来启动应用程序。

故障排除

如果你安装了 bumblebee,你应该将其卸载,因为它会列出 nvidia_drm 驱动程序的黑名单,而该驱动程序是 X 服务器进行卸载所必需的。

PRIME 同步

使用 PRIME 时,主 GPU 渲染屏幕内容/应用程序,并将其传递给辅助 GPU 进行显示。引用 一个 NVIDIA 论坛帖,"传统的垂直同步 (vsync) 可以将应用程序的渲染与系统内存的复制同步,但需要一种额外的机制将系统内存的复制与 iGPU 的显示引擎同步。与传统的垂直同步不同,这种机制必须涉及 dGPU 和 iGPU 驱动程序之间的通信。"

这种同步通过 PRIME 同步实现。要检查显示器是否启用了 PRIME 同步,请检查 xrandr --prop 的输出。

要启用它,请运行:

$ xrandr --output <output-name> --set "PRIME Synchronization" 1

反向 PRIME

本文章或章节需要扩充。

原因: 缺少关于为开源和闭源 amdgpu 驱动程序配置 Intel + AMD 反向 PRIME 的信息(在 Talk:PRIME 中讨论)
  • 在 470 Beta 之前的 NVIDIA 驱动上,AMD + NVIDIA 不支持反向 PRIME。更多详情请参见 [7]
  • 目前,当仅启用外部显示器时,你只会获得 1 FPS。更多详情请参见 [8]

如果第二个 GPU 具有主 GPU 无法访问的输出接口,你可以使用 反向 PRIME 来利用它们。这将涉及使用主 GPU 渲染图像,然后将其传递给第二个 GPU。

它可能开箱即用,但如果没有,请执行以下步骤。

配置

本文或本节需要在语言、wiki 语法或风格方面进行改进。请参阅 Help:Style 获取参考。

原因: 本节前半部分是 Intel + NVIDIA,后半部分是 Intel + Radeon。识别 GPU 总线 ID 应该委托给一个通用章节。(在 Talk:PRIME 中讨论)

首先,确定集成 GPU 的 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 显卡的地址为 00:02.0,转换为 PCI:0:2:0

按照如下方式设置你的 xorg.conf 并调整 BusID。

/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

得益于 AutoBindGPU[9],辅助 GPU 将自动设置为输出接收端和卸载源。如果未发生这种情况,或者你想自行配置,请运行 xrandr --setprovideroutputsource provider source 将提供程序设置为源的输出。例如:

$ xrandr --listproviders
Providers: number : 2
Provider 0: id: 0x48 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 4 outputs: 6 associated providers: 1 name:modesetting
Provider 1: id: 0x257 cap: 0x2, Sink Output crtcs: 4 outputs: 5 associated providers: 1 name:NVIDIA-G0
$ xrandr --setprovideroutputsource NVIDIA-G0 modesetting

完成后,独立显卡的输出接口应出现在 xrandr 中,你可以执行类似以下操作:

$ xrandr --output HDMI-1 --auto --above LVDS1

来配置内部和外部显示器。

已知问题

如果重启后你只有一个提供程序,可能是因为 Xorg 启动时 nvidia 模块尚未加载。你需要启用早期模块加载。详情请参阅 NVIDIA#Early loading

故障排除

本文或本章节的准确性存在争议。

原因: 没有来源来支持本节中的变通方法(在 Talk:PRIME 中讨论)

XRandR 仅指定 1 个输出提供程序

删除/移动 /etc/X11/xorg.conf 文件以及 /etc/X11/xorg.conf.d/ 中任何与 GPU 相关的其他文件。在此更改后重启 X 服务器。

如果视频驱动程序在 /etc/modprobe.d//usr/lib/modprobe.d/ 中被列入黑名单,请加载模块并重启 X。如果你对 NVIDIA GPU 使用 bbswitch 模块,可能会出现这种情况。

另一个可能的问题是 Xorg 可能会尝试自动将监视器分配给第二个 GPU。请检查日志:

$ grep "No modes" ~/.local/share/xorg/Xorg.0.log
AMDGPU(0): No modes.

要解决此问题,请在 xorg.conf 中添加带有 inactive 设备的 ServerLayout 部分:

/etc/X11/xorg.conf
Section "ServerLayout"
  Identifier     "X.org Configured"
  Screen      0  "Screen0" 0 0 # Screen for your primary GPU
  Inactive       "Card1"       # Device for your second GPU
EndSection

当应用程序使用独立显卡渲染时,仅显示黑屏

在某些情况下,PRIME 需要合成管理器才能正常工作。如果你的窗口管理器不处理合成,你可以在其上使用一个 合成器

如果你使用 Xfce,可以进入 菜单 > 设置 > 窗口管理器微调 > 合成器 并启用合成,然后重试你的应用程序。

基于 GL 的合成器黑屏

目前,基于 GL 的合成器和 PRIME 卸载存在问题。虽然基于 Xrender 的合成器(xcompmgr、xfwm、compton 的默认后端、cairo-compmgr 等)可以正常工作,但基于 GL 的合成器(Mutter/muffin、Compiz、带 GLX 后端的 compton、Kwin 的 OpenGL 后端等)最初会显示黑屏,就像没有运行合成器一样。虽然你可以通过调整卸载窗口的大小来强制显示图像,但这并不是一个实用的解决方案,因为它不适用于全屏 Wine 应用程序等情况。这意味着 GNOME3 和 Cinnamon 等桌面环境在使用 PRIME 卸载时存在问题。

此外,如果你使用的是 Intel IGP,你或许可以通过将 IGP 作为 UXA 而不是 SNA 运行来修复 GL 合成问题,但这也可能导致卸载过程出现问题(例如,xrandr --listproviders 可能不会列出独立 GPU)。

详情请参见 FDO Bug #69101

解决此问题的另一种方法是在 Intel 驱动程序中启用 DRI3。请参阅下面的问题以获取示例配置。

GNOME

你可能会发现 禁用全屏取消重定向 (fullscreen undirect) 可以使 PRIME 卸载在全屏应用程序上正常工作。

使用 PRIME 和切换窗口/工作区时发生内核崩溃/oops

注意 此问题已在 Intel+AMD 系统上进行了测试。

使用带有集成显卡配置文件的 DRI3 似乎可以解决此问题。

要启用 DRI3,你需要为集成显卡创建一个配置,添加 DRI3 选项:

Section "Device"
    Identifier "Intel Graphics"
    Driver "intel"
    Option "DRI" "3"
EndSection

之后,你可以使用 DRI_PRIME=1 而无需运行 xrandr --setprovideroffloadsink radeon Intel,因为 DRI3 将处理卸载。

使用反向 PRIME 时,第二个显示器出现故障/重影同步问题

当不使用 合成管理器(例如在 i3 中)时,此问题可能会影响用户。[10]

如果你在 Gnome 下遇到此问题,一个可能的解决方法是在 /etc/environment 中设置一些环境变量 [11]

CLUTTER_PAINT=disable-clipped-redraws:disable-culling
CLUTTER_VBLANK=True

启动 GL 应用程序时报错 "radeon: Failed to allocate virtual address for buffer:"

当内核驱动程序中的电源管理正在运行时,会出现此错误。你可以通过在 引导加载程序 的内核参数中添加 radeon.runpm=0 来克服此错误。

使用闭源驱动和反向 PRIME 时,启用 VSync 的 Vulkan 应用程序/游戏持续卡死/冻结

某些 Vulkan 应用程序(特别是使用 VK_PRESENT_MODE_FIFO_KHR 和/或 VK_PRESENT_MODE_FIFO_RELAXED_KHR 的应用程序,包括使用 DXVK 运行的 Windows 游戏)在反向 PRIME 系统上运行时会导致 GPU 持续锁定(~5-10 秒冻结,~1 秒正常工作)[12]

GPU 锁定将使任何输入变得不可用(包括切换 TTY 和使用 SysRq 功能)。

目前没有针对此 NVIDIA bug 的已知修复程序,但存在一些变通方法:

  • 关闭 Vsync(某些应用程序无法关闭)。
  • 关闭 PRIME 同步[13](会导致屏幕撕裂)。
xrandr --output HDMI-0 --set "PRIME Synchronization" 0 #replace HDMI-0 with your xrandr output ID

你可以通过从 vulkan-tools 包运行 vkcube 来简单地验证你的配置是否受此问题影响。

在 Wayland 下打开某些程序时有延迟

如果你启用了 RTD3(来自 #NVIDIA),在使用 Wayland 时,打开某些程序会遇到一些延迟。根据应用程序的不同,这可能由两个源引起:Vulkan 或 OpenGL,但引起延迟的机制相同。两者都必须确定要委托给哪个设备。此决策基于配置文件。对于 OpenGL,配置文件位于 /usr/share/glvnd/egl_vendor.d/,而对于 Vulkan,它们位于 /usr/share/vulkan/icd.d/。实际的延迟是由确定候选者需要迭代所有潜在的渲染配置引起的。即使首选配置出现在其他配置之前(即数字较小,iGPU 在外部 GPU 之前),它仍会遍历所有可用选项。在尝试休眠的(外部)GPU 配置时,它会被唤醒(这需要 ~1 秒或更长时间),然后再委托打开程序,浪费了时间和电池寿命。这是一个 NVIDIA 驱动程序问题。更多详情请点击此处。

一种解决方案是确保独立 GPU 不被启动,即确保它不被迭代。这可以通过将配置显式设置为环境变量来实现。这些变量可以直接在运行程序时传递,也可以全局设置(例如在你的 /etc/environment 文件中)。请注意,全局设置该变量需要你在刻意尝试使用外部 GPU 运行程序时取消设置该变量(或者将其分别设置为 nvidia 文件)。

/etc/environment
__EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json
VK_DRIVER_FILES=/usr/share/vulkan/icd.d/intel_icd.json
__GLX_VENDOR_LIBRARY_NAME=mesa

运行带有 DXVK 的 Wine 游戏时报错

使用 PRIME 卸载时,遇到 Major opcode of failed request: 156 (NV-GLX) 是一个已知问题。唯一的已知变通方法是将 X 会话 完全在 NVIDIA GPU 上启动。在仅使用 NVIDIA 和 PRIME 卸载方法之间切换的一种用户友好的方式是使用 optimus-manager 工具,或自己编写一些自动化脚本。

Wayland 上 Vulkan/OpenGL 应用程序段错误 (segfault)

VK_KHR_wayland_surface 需要内核模式设置。如果你正在使用 Wayland 合成器且无法在 dGPU 上启动应用程序而必须强制它们在 Xwayland 下运行,请确保启用了模式设置。

这意味着如果内核参数中存在 nvidia_drm.modeset=0,请将其移除。

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.