外接顯卡 - Arch Linux 中文维基

跳至內容

# 外接顯卡

出自 Arch Linux 中文维基

相關文章

- Xorg
- PRIME
- Thunderbolt
- NVIDIA Optimus
- NVIDIA/Tips and tricks
- Docking

翻譯狀態：

- 本文（或部分內容）譯自 External GPU，最近一次同步於 2024-07-20，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

在搭載了雷電 3+ 或 USB4的設備上，可以通過顯卡拓展塢連接一張桌面級的外接顯卡（eGPU）。eGPU.io 是一個專門討論外接顯卡的社區論壇。儘管大多數時候仍需一些手動配置（如下），Linux 對外接顯卡的支持相當不錯。

注意：對於搭載了 USB4 的筆記本，其傳輸速率一般被設置為最小值（20 Gbit/s）。可以手動將其設置得更高（40，80 或更高）來獲取更佳的體驗。如果您的拓展塢使用雷電接口，可以啟用筆記本的 USB4 模式來達到相同效果。

## 安裝

### 雷電

使用雷電接口的拓展塢在插入前可能首先需要經過設備認證（取決於 BIOS/UEFI 配置）。詳見 Thunderbolt#User device authorization。如果成功插入，外接顯卡將在 `lspci` 中顯示。

    $ lspci | grep -E 'VGA|3D'

    00:02.0 VGA compatible controller: Intel Corporation UHD Graphics 620 (rev 07)             # 集成顯卡
    1a:10.3 VGA compatible controller: NVIDIA Corporation GP107 [GeForce GTX 1050] (rev a1)    # 外接顯卡

根據電腦的硬體和拓展塢的硬體情況，雷電接口會限制主機與外接顯卡間的帶寬。限制程度取決於 PCIe 通道數和封裝的DMI互聯接口（OPI）模式：

    # dmesg | grep PCIe

    [19888.928225] pci 0000:1a:10.3: 8.000 Gb/s available PCIe bandwidth, limited by 2.5 GT/s PCIe x4 link at 0000:05:01.0 (capable of 126.016 Gb/s with 8.0 GT/s PCIe x16 link)

### 驅動

您應該安裝與您的外接顯卡兼容的驅動程序：

- AMDGPU AMD 驅動
- NVIDIA 專有 NVIDIA 驅動
- Nouveau 開源 NVIDIA 驅動

成功安裝後，`lspci -k` 應當顯示顯卡與驅動已經成功綁定：

    $ lspci -k

    1a:10.3 VGA compatible controller: NVIDIA Corporation GP107 [GeForce GTX 1050] (rev a1)
            Subsystem: NVIDIA Corporation GP107 [GeForce GTX 1050]
            Kernel driver in use: nvidia
            Kernel modules: nouveau, nvidia_drm, nvidia

注意，在某些情況下，AMDGPU 驅動（無論使用雷電接口還是 USB4）可能會被設置為錯誤的 pcie_gen_gap 模式，然後回滾到 PCIe 1.1 的速率。這可能會導致性能嚴重降低。 可以通過調整模塊參數（見內核模塊#使用 /etc/modprobe.d/中的文件) 或傳遞內核參數來解決以上問題。

    /etc/modprobe.d/amd-egpu-pcie-speed.conf

    options amdgpu pcie_gen_cap=0x40000

這會將速率設置為 PCIe 3 模式。完整的參數選項見 amd_pcie.h。

## 顯卡計算

在完成 #安裝之後，像 GPGPU#CUDA 這樣無需在屏幕上顯示的純計算工作，理論上無需額外配置即可使用。nvidia-smi 工具（由 nvidia-utils包 提供）在使用專有 NVIDIA 驅動時應該能正常運行。專有的 NVIDIA NVENC/NVDEC 也應該正常運行（不包括與 OpenGL 的互操作）。

在這種使用場景下，熱插拔也應該受支持（對拔出支持取決於驅動程序）。不過，對於 NVIDIA 設備，使用 `nvidia-persistenced` 會導致熱拔出時設備出現故障。

## Xorg

通過一些額外配置，您可以將集成顯卡（iGPU）和外接顯卡（eGPU）結合起來使用。這樣配置有其優點，但也會帶來一些額外的問題。

### Xorg 在外接顯卡上渲染，PRIME 顯示分載到集成顯卡

- 大多數使用顯卡的程序可以正常執行在外接顯卡上：`glxinfo`/`glxgears`, `eglinfo`/`eglgears_x11`, `NVENC`/`NVDEC`（包括與 OpenGL 的互操作）。
- Xorg 僅能在外接顯卡接入後啟動。
- 連接到外接顯卡上的顯示器開箱即用，而 PRIME顯示分載適用於連接到集成顯卡的顯示器（例如筆記本內屏）。

有關這些內容，見 PRIME#將獨立顯卡作為主 GPU 和 PRIME#反向 PRIME。 同時，NVIDIA 官方驅動文檔也有教程： Chapter 33. Offloading Graphics Display with RandR 1.4.

Xorg 的配置文件應該像如下所示：

    /etc/X11/xorg.conf.d/80-egpu-primary-igpu-offload.conf

    Section "Device"
        Identifier "Device0"
        Driver     "nvidia"
        BusID      "PCI:26:16:3"                 # 根據 lspci 填寫，將十六進制轉換為十進制。
        Option     "AllowExternalGpus" "True"    # 專有 NVIDIA
     驅動所需。
    EndSection

    Section "Module"
        # 為集成顯卡加載 modesetting 模塊，其提供程序應當是 XrandR 1.4。
        Load "modesetting"
    EndSection

注意：Xorg 使用十進制的總線 ID，但大多數工具使用十六進制。在 `xorg.conf` 中，必須將形如 `1a:10.3` 的總線 ID轉換為 `26:16:3`。
提示：在更新的 Xorg 中，無需指定 `ServerLayout` 和 `Screen` 項，這些項將會被自動推斷。 第一個定義的 `Device` 會被首先考慮。

要確認此次設置是否有效，使用 `xrandr --listproviders` 檢查。輸出應當如下：

    Providers: number : 2
    Provider 0: id: 0x1b8 cap: 0x1, Source Output crtcs: 4 outputs: 4 associated providers: 0 name:NVIDIA-0
    Provider 1: id: 0x1f3 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 3 outputs: 5 associated providers: 0 name:modesetting

要輸出到筆記本內屏及其他連接到集成顯卡上的顯示，可以使用 RandR 1.4 PRIME顯示分載。請使用 `xrandr --listproviders` 輸出的設備名：

    xrandr --setprovideroutputsource modesetting NVIDIA-0 && xrandr --auto

注意：`xrandr --auto` 是可選的命令，可以使用其他任何基於 RandR 的顯示配置工具替代。這條命令只是防止出現屏幕全黑的情況。

要在顯示管理器彈出登錄頁面或啟動桌面環境之前執行這條命令，見 Xrandr#Configuration 和 Xinit。

Vulkan 可能會自行枚舉 Xorg 上的所有顯卡，所以如果要在本配置下執行如 `vkcube` 這樣的程序，可能需要傳遞參數 `--gpu_number 1`。另外，也可以使用此參數以在枚舉期間對顯卡重新排序：`__NV_PRIME_RENDER_OFFLOAD=1 vkcube` 或者等效的 `prime-run vkcube`。

提示：在筆記本上使用 optimus-manager 時，僅需將外接顯卡的 `BusID` 放入位於 `/etc/optimus-manager/xorg/` 下的管理模式與顯卡的配置文件中，就可以在外接顯卡上渲染。

### Xorg 在集成顯卡上渲染，PRIME 渲染分載到外接顯卡

- 程序默認在集成顯卡上渲染，但 PRIME 渲染分載可以使程序在外接顯卡上渲染。
- Xorg 可以在未連接外接顯卡時啟動，但在連接外接顯卡後，必須重啟 Xorg 才能使用渲染與顯示分載。
- 連接到集成顯卡上的顯示器（例如筆記本內屏）開箱即用，而 PRIME 顯示分載適用於連接到外接顯卡上的顯示器。

詳細內容見 PRIME#PRIME 顯卡分載。NVIDIA 官方驅動文檔中也有記錄：Chapter 34. PRIME Render Offload。

對大多數獨立顯卡而言，此模式應當是默認模式，無需手動配置 Xorg。如果存在問題，或是在使用專有 NVIDIA 驅動，應當如下配置：

    /etc/X11/xorg.conf.d/80-igpu-primary-egpu-offload.conf

    Section "Device"
        Identifier "Device0"
        Driver     "modesetting"
    EndSection

    Section "Device"
        Identifier "Device1"
        Driver     "nvidia"
        BusID      "PCI:26:16:3"                 # 根據 lspci 填寫，將十六進制轉換為十進制。
        Option     "AllowExternalGpus" "True"    # 專有 NVIDIA 驅動所需。
    EndSection

要確認是否配置成功，執行 `xrandr --listproviders` 時，應當顯示如下內容：

    $ xrandr --listproviders

    Providers: number : 2
    Provider 0: id: 0x47 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 3 outputs: 5 associated providers: 0 name:modesetting
    Provider 1: id: 0x24a cap: 0x2, Sink Output crtcs: 4 outputs: 4 associated providers: 0 name:NVIDIA-G0

本文或本章節可能需要合併到PRIME#配置應用程式使用 GPU 渲染。

附註： 也許應該在專門的頁面探討這些問題，而不是在這裡。（在 Talk:外接顯卡 中討論）

要讓某些程序在外接顯卡上渲染，可以用以下方式啟用 PRIME 渲染分載：

- 對於專有 NVIDIA 驅動：

      $ __NV_PRIME_RENDER_OFFLOAD=1 __VK_LAYER_NV_optimus=NVIDIA_only __GLX_VENDOR_LIBRARY_NAME=nvidia some_program

- 對於專有 NVIDIA 驅動（封裝版）：

      $ prime-run some_program

- 對於開源驅動：

      $ DRI_PRIME=1 some_program

要輸出到連接至外接顯卡的顯示器，還可以這樣使用 RandR 1.4 PRIME 顯示分載：

    $ xrandr --setprovideroutputsource NVIDIA-G0 modesetting && xrandr --auto

提示：提供程序的順序並不相同，同時 NVIDIA 的命名也稍有不同。

NVIDIA 驅動版本 460.27.04+ 優化了在一些特定情形下對渲染和顯示分載的結合支持：

  添加了對 「反向 PRIME 繞行」（Reverse PRIME Bypass）的支持，這使得當某一渲染分載程序處於全屏，非重定向，且僅在給定的使用 NVIDIA 驅動的 PRIME 顯示分載輸出中顯示時，可以繞過 PRIME 渲染分載和 PRIME 顯示分載的帶寬限制。當 X 伺服器啟用詳細日誌時，可以在 X 日誌中找到此特性的使用情況。

### 在外接顯卡上執行多個獨立 Xorg 實例

詳見 Nvidia-xrun#External GPU setup.

### 在 Xorg 上使用外接顯卡的已知問題

- 大多數獨立顯卡的 Xorg 驅動不支持熱插入：必須在啟動 Xorg 前插入外接顯卡。註銷後重新登錄即可重啟 Xorg。
- 完全不支持熱拔出：這樣會導致系統不穩定或卡死（根據 NVIDIA 官方文檔）。

## Wayland

有關 Wayland 對外接顯卡（或多顯卡）支持程度的測試目前尚為數不多，不過理論上其相對於 Xorg 來說配置會更為便捷。

需要注意的是，Wayland 混成器尚無對顯卡熱插拔的明確支持，不過大多數混成器已經在某種程度上支持了：

- KDE's kwin: https://invent.kde.org/plasma/kwin/-/merge_requests/811
- GNOME's Mutter: https://gitlab.gnome.org/GNOME/mutter/-/issues/17, https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1562
- wl-roots: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/1278

使用開源驅動時，需要這樣執行 DRI 分載：

    $ DRI_PRIME=1 some_program

一些像 all-ways-egpu 這樣的項目正致力於在 Wayland 下提供更為便捷的顯卡切換方法。

### 熱插拔 NVIDIA 外接顯卡

Wayland 支持在使用 PRIME 時熱插拔外接顯卡。NVIDIA 獨立顯卡對 PRIME 的優秀支持同樣適用於外接顯卡。

首先，確保沒有進程正在使用 NVIDIA 模塊。每個 EGL 程序會占用 1MB 的獨顯顯存，即使其運行在集成顯卡上。可以通過 `nvidia-smi` 查看是否有此類進程。 為防止出現此類問題，請將`__EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json` 設置為環境變量。 不過，最好將其放在 `/etc/environment.d/50_mesa.conf` 中。

然後，卸載 NVIDIA 模塊：

    # rmmod nvidia_uvm
    # rmmod nvidia_drm
    # rmmod nvidia_modeset
    # rmmod nvidia

模塊卸載完成後，就可以連接外接顯卡。顯卡初始化完畢後，使用 `modprobe nvidia-drm` 或 `modprobe nvidia-current-drm` 重新加載 NVIDIA 模塊。使用哪條命令取決於模塊的來源，例如從 NVIDIA 官網下載或是使用軟體包管理器直接安裝。在某些情況下（例如 GIGABYTE AORUS GAMING BOX）外接顯卡可能不兼容專有驅動，因此需要使用開源驅動的命令：`modprobe nvidia-current-open-drm`。

模塊加載成功後，PRIME 就應該能正常使用，不過因為我們設置了 `__EGL_VENDOR_LIBRARY_FILENAMES` 變量來使用 MESA，所以在啟動程序前需要添加 `__EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/10_nvidia.json`。完整的環境變量列表如下：

    __GLX_VENDOR_LIBRARY_NAME=nvidia __NV_PRIME_RENDER_OFFLOAD=1 __VK_LAYER_NV_optimus=NVIDIA_only __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/10_nvidia.json %command%

對於 GNOME 用戶，可能需要修補 switcheroo-control包 來將 `__EGL_VENDOR_LIBRARY_FILENAMES` 包含到環境變量中。這將允許程序原生運行在外接顯卡上，不會出現滑鼠錯位，而且能「使用獨立顯卡啟動」。不過，關於如何修補，就不在本篇文章的討論範圍之內了。

### 熱插拔 NVIDIA 外接顯卡，並臨時停用 NVIDIA 獨立顯卡

如果您同時擁有集成顯卡（iGPU）和 NVIDIA 獨立顯卡（dGPU），並且嘗試連接 NVIDIA 外接顯卡（eGPU），顯卡間會產生衝突，這會導致只有獨立顯卡能夠使用。要解決衝突，必須臨時停用獨立顯卡，這樣 NVIDIA 驅動就不會識別到它。最好的方法就是覆蓋驅動。

首先，卸載 NVIDIA 驅動模塊：

    # rmmod nvidia_uvm
    # rmmod nvidia_drm
    # rmmod nvidia_modeset
    # rmmod nvidia

然後，使用 driverctlAUR 工具覆蓋獨立顯卡驅動。在下面的例子中，使用 0000:01:00.0 代表獨立顯卡的地址。您設備的獨立顯卡地址可以使用 `lspci` 查看。

    # driverctl --nosave set-override 0000:01:00.0 vfio-pci

建議使用參數 `--nosave`，否則 driverctl 會在系統啟動時覆蓋驅動。這樣，在出錯的時候，僅需重啟就可以恢復獨立顯卡。

獨立顯卡禁用後，就可以使用 `modprobe nvidia-drm` 加載內核模塊，然後使用 `nvidia-smi` 檢查其顯示一張或兩張顯卡。

重新啟動獨立顯卡有點麻煩，因為它很反直覺。首先，卸載 NVIDIA 模塊，拔出外接顯卡，然後執行以下命令：

    # modprobe nvidia-current
    # driverctl --nosave unset-override 0000:01:00.0
    # modprobe nvidia-current
    # driverctl --nosave unset-override 0000:01:00.0
    # modprobe nvidia-current-modeset
    # modprobe nvidia-current-drm

前兩個命令需要執行兩次，這看起來儘管很奇怪，不過只有這樣才能重新啟動獨立顯卡。第一次執行命令時可能會報錯，不過這並不重要。

分類：​

- 圖形
- X 伺服器

隱藏分類：​

- 使用「模板:合併」標記的頁面或章節

外接顯卡
新增話題