跳至內容
出自 Arch Linux 中文维基

混合圖形技術是指在同一計算機上包含兩張顯卡。筆記本電腦製造商將兩張性能和功耗不同的顯卡置入一台筆記本電腦,使用混合圖形技術來同時支持高性能和節能的使用場景,即在集成顯卡的 3D 渲染性能不夠用時使用專用/獨立顯卡。

有許多技術用於應對該問題,許多製造商也開發了自己的解決方案。這項技術在 Windows 上支持完善,但在 Linux 上依然不夠完善。本文將簡要解釋一些方法和社區解決方案,以應對供應商對 GNU/Linux 缺乏支持的現況。

注意:除非您的設備生產於 2010 年前,否則其應當可以使用動態切換方法。以前的混合圖形解決方案要麼需要簡單粗暴地重啟電腦,要麼需要重啟整個圖形棧(還得重新登錄)才能生效。

動態切換

大部分較新的混合圖形技術使用兩張顯卡:一張專用/獨立顯卡,一張集成顯卡,通過幀緩衝區進行協調,沒有硬體多路復用器。集成顯卡一直開啟,而專用顯卡僅在有高性能渲染需求時啟用,節電時停用。大部分情況下無法使用專用顯卡,且所有切換和渲染都由軟體控制。 啟動時,Linux 內核開始使用視頻模式並設定低級圖形驅動(low-level graphic drivers),這會被應用程式使用。大部分 Linux 發行版使用 X.org 創建圖形環境。最後,一些其他軟體被啟動,先是登錄管理器,然後是窗口管理器,再往後是其它軟體。這個等級制的系統被設計為在單顯卡的系統上使用。

注意:請參閱 NVIDIA OptimusBumblebee 以了解使用 NVIDIA 專有驅動的混合圖形技術的詳細信息。請參閱 PRIME 以了解更為全面的(包括 AMDGPUnouveauNVIDIA 專有驅動)方案。

完全關閉專用顯卡

您可能想完全關閉高性能顯卡以節省電池電量。

使用 BIOS/UEFI

一些筆記本電腦製造商在 BIOS 或 UEFI 添加了切換開關,用以禁用專用顯卡。

使用 udev 規則

確保移除了所有與 NVIDIA 有關的顯示管理器配置。

將 nouveau 驅動加入禁用列表:

/etc/modprobe.d/blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0

然後創建:

/etc/udev/rules.d/00-remove-nvidia.rules
# 如果 NVIDIA USB xHCI Host Controller 設備存在,則將其移除
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c0330", ATTR{power/control}="auto", ATTR{remove}="1"

# 如果 NVIDIA USB Type-C UCSI 設備存在,則將其移除
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c8000", ATTR{power/control}="auto", ATTR{remove}="1"

# 如果 NVIDIA Audio 設備存在,則將其移除
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x040300", ATTR{power/control}="auto", ATTR{remove}="1"

# 移除NVIDIA VGA/3D controller 設備
ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x03[0-9]*", ATTR{power/control}="auto", ATTR{remove}="1"

重啟並執行 lspci 以查看您的 NVIDIA GPU 是否還在。

檢查電量消耗以確保 GPU 沒有偷偷耗電。如果依然耗電,或許可以使用 acpi_call 將其完全關閉。

使用 bbswitch

使用 NVIDIA GPU 時,這可以由 bbswitch 更安全地完成,其由一個內核包構成,會自動發出正確的 ACPI 信號以在不需要時禁用專用 GPU,或開機自動禁用。

注意:bbswitch 從內核版本 4.8 開始不使用 PCI-E 接口電源管理方法。請參閱 Bumblebee#Broken power management with kernel 4.8 以了解詳細信息。
譯者註:由於 Bumblebee 頁面年久失修,因此上述連結的段落不存在於本維基,您需要前往英文 ArchWiki 的相應頁面查看。

使用 acpi_call

另外,對於 bbswitch 不支持的 GPU,相同的效果可以由手動安裝的 acpi_call 來完成。

提示:對於不在官方倉庫內的內核,可以改為安裝 acpi_call-dkms,另見 DKMS

安裝後加載內核模塊:

# modprobe acpi_call

內核模塊加載後,執行位於 /usr/share/acpi_call/examples/turn_off_gpu.sh 的腳本。

該腳本會遍歷並嘗試關閉所有的數據總線,您會看到類似如下的輸出:

# /usr/share/acpi_call/examples/turn_off_gpu.sh
Trying \_SB.PCI0.P0P1.VGA._OFF: failed
Trying \_SB.PCI0.P0P2.VGA._OFF: failed
Trying \_SB_.PCI0.OVGA.ATPX: failed
Trying \_SB_.PCI0.OVGA.XTPX: failed
Trying \_SB.PCI0.P0P3.PEGP._OFF: failed
Trying \_SB.PCI0.P0P2.PEGP._OFF: failed
Trying \_SB.PCI0.P0P1.PEGP._OFF: failed
Trying \_SB.PCI0.MXR0.MXM0._OFF: failed
Trying \_SB.PCI0.PEG1.GFX0._OFF: failed
Trying \_SB.PCI0.PEG0.GFX0.DOFF: failed
Trying \_SB.PCI0.PEG1.GFX0.DOFF: failed
Trying \_SB.PCI0.PEG0.PEGP._OFF: works!
Trying \_SB.PCI0.XVR0.Z01I.DGOF: failed
Trying \_SB.PCI0.PEGR.GFX0._OFF: failed
Trying \_SB.PCI0.PEG.VID._OFF: failed
Trying \_SB.PCI0.PEG0.VID._OFF: failed
Trying \_SB.PCI0.P0P2.DGPU._OFF: failed
Trying \_SB.PCI0.P0P4.DGPU.DOFF: failed
Trying \_SB.PCI0.IXVE.IGPU.DGOF: failed
Trying \_SB.PCI0.RP00.VGA._PS3: failed
Trying \_SB.PCI0.RP00.VGA.P3MO: failed
Trying \_SB.PCI0.GFX0.DSM._T_0: failed
Trying \_SB.PCI0.LPC.EC.PUBS._OFF: failed
Trying \_SB.PCI0.P0P2.NVID._OFF: failed
Trying \_SB.PCI0.P0P2.VGA.PX02: failed
Trying \_SB_.PCI0.PEGP.DGFX._OFF: failed
Trying \_SB_.PCI0.VGA.PX02: failed

看到 "works" 了麼?這說明腳本找到了一個 GPU 所在的總線並已將該 GPU 關閉。您的電池續航延長應當能夠證明這一點。

提示:若您在禁用 GPU 後遇到系統休眠和掛起問題,請嘗試通過向其發送相應的 acpi_call 以重新啟用它,另見電源管理/掛起與休眠#自定義 systemd 單元
自動關閉 GPU

目前,GPU 會在下次啟動時重新啟用,欲解決,請在啟動時加載模塊

/etc/modules-load.d/acpi_call.conf
#Load 'acpi_call.ko' at boot.
acpi_call
在啟動時加載

可以使用 systemd-tmpfiles 在啟動時關閉 GPU:

/etc/tmpfiles.d/acpi_call.conf

w /proc/acpi/call - - - - \\_SB.PCI0.PEG0.PEGP._OFF

以上配置會在啟動時被 systemd 加載。其將特定的 OFF 信號寫入 /proc/acpi/call 文件。顯然您需要將配置中的 \_SB.PCI0.PEG0.PEGP._OFF 修改為適用於您的系統的配置(注意您需要轉義反斜槓)。

在 X 伺服器初始化後加載

在部分系統上,在 X 伺服器初始化前禁用專用 GPU 可能導致系統掛起。這種情況下,在 X 伺服器初始化後可能是個更好的選擇,可以由顯示管理器來完成。在 LightDM 上,一個 display-setup-script seat 配置參數能夠以 root 權限執行禁用 GPU 的腳本。如果使用 SDDM 則可以將 echo "\_SB.PCI0.PEG0.PEGP._OFF" > /proc/acpi/call 添加到 /usr/share/sddm/scripts/wayland-session/usr/share/sddm/scripts/Xsession,分別對應使用 WaylandXorg,將 \_SB.PCI0.PEG0.PEGP._OFF 修改為適用於您的系統的配置。

System76

一些 System76 筆記本(如 Oryx Pro)有其自己的混合圖形選項。欲使用其自己的混合圖形選項,請安裝 system76-powerAUR啟用 system76-power.service 並運行 system76-power graphics hybrid

完全關閉專用 GPU

首先運行 system76-power graphics integrated 以確保您正在使用集成圖形模式,然後重啟電腦。在集成模式內,執行 system76-power graphics power off 以關閉專用 GPU,該命令並非永久生效,需要每次啟動都執行一次。

疑難解答

部分應用程式啟動時間延遲 30 秒

本文或本章節可能需要合併到Vulkan

附註:Vulkan#AMDGPU - Vulkan 應用程式啟動過慢 及其相似,只是本文完全沒有為相應的環境變量設定適當的參數。(在 Talk:混合圖形技術 中討論)

Vulkan 在被調用時會嘗試初始化 /usr/share/vulkan/icd.d/nvidia_icd.json 中指定的可安裝客戶端驅動程序(Installable Client Driver,ICD),nvidia-utils 配置該文件引用 libGLX_nvidia 驅動,以向 Vulkan 提供 GPU 驅動的路徑。然而,若 GPU 被禁用,該驅動會初始化失敗,導致部分應用程式(如基於 Chromium/Electron 的應用程式)啟動需要等待 30 秒的超時。欲阻止 Vulkan 加載驅動以減緩超時,您可以使用 VK_DRIVER_FILES 環境變量覆蓋 ICD JSON 文件的路徑:

$ export VK_DRIVER_FILES=

禁用 NVIDIA 專用 GPU 後依然高功耗

如果使用 acpi_call 禁用專用 GPU 後功耗依然居高不下,請使用 lsmod 檢查 nouveau 內核模塊是否被加載,若沒有則確保其已被安裝,/etc/modprobe.d/ 中所有 .conf 文件中屏蔽 Nouveau 的條目被移除,並且 Nouveau 內核模塊在啟動時被自動加載。重啟後功耗應該就降低了。

提示:請參閱內核模塊以了解更多關於內核模塊加載和屏蔽的詳細信息。
注意:如果重啟後亮度控制出現問題,/sys/class/backlight 有多個目錄,請將 acpi_backlight=native 添加到內核參數