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 工具或自己編寫一些自動化腳本。