混合圖形技術是指在同一計算機上包含兩張顯卡。筆記本電腦製造商將兩張性能和功耗不同的顯卡置入一台筆記本電腦,使用混合圖形技術來同時支持高性能和節能的使用場景,即在集成顯卡的 3D 渲染性能不夠用時使用專用/獨立顯卡。
有許多技術用於應對該問題,許多製造商也開發了自己的解決方案。這項技術在 Windows 上支持完善,但在 Linux 上依然不夠完善。本文將簡要解釋一些方法和社區解決方案,以應對供應商對 GNU/Linux 缺乏支持的現況。
動態切換
大部分較新的混合圖形技術使用兩張顯卡:一張專用/獨立顯卡,一張集成顯卡,通過幀緩衝區進行協調,沒有硬體多路復用器。集成顯卡一直開啟,而專用顯卡僅在有高性能渲染需求時啟用,節電時停用。大部分情況下無法僅使用專用顯卡,且所有切換和渲染都由軟體控制。 啟動時,Linux 內核開始使用視頻模式並設定低級圖形驅動(low-level graphic drivers),這會被應用程式使用。大部分 Linux 發行版使用 X.org 創建圖形環境。最後,一些其他軟體被啟動,先是登錄管理器,然後是窗口管理器,再往後是其它軟體。這個等級制的系統被設計為在單顯卡的系統上使用。
完全關閉專用顯卡
您可能想完全關閉高性能顯卡以節省電池電量。
使用 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,或開機自動禁用。
- 譯者註:由於 Bumblebee 頁面年久失修,因此上述連結的段落不存在於本維基,您需要前往英文 ArchWiki 的相應頁面查看。
使用 acpi_call
另外,對於 bbswitch 不支持的 GPU,相同的效果可以由手動安裝的 acpi_call包 來完成。
安裝後加載內核模塊:
# 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
目前,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
,分別對應使用 Wayland 或 Xorg,將 \_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 在被調用時會嘗試初始化 /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 內核模塊在啟動時被自動加載。重啟後功耗應該就降低了。