# GPU分区(将物理GPU共享给虚拟机)<no value>

## 什么是GPU分区?
GPU 分区（GPU Partitioning）是一种允许多台虚拟机（VM）共享同一块物理 GPU 的技术，通过将 GPU 的资源（如图形处理单元、显存等）划分为多个部分，每个部分可以被不同的虚拟机或应用程序使用。GPU 分区的目标是提高 GPU 的资源利用率，使多个虚拟机在运行过程中能够共享和并行使用一块 GPU，而无需为每个虚拟机配备独立的 GPU。

###### GPU 分区的工作原理
GPU 分区通过虚拟化技术将物理 GPU 的计算和显存资源划分成多个逻辑分区。每个逻辑分区像是一个独立的虚拟 GPU，虚拟机可以访问并使用它们来进行图形加速、计算或渲染任务。这个过程通常通过硬件级别的支持（如 NVIDIA vGPU 技术或 AMD SR-IOV 技术）来实现，确保物理 GPU 能被多个虚拟机高效共享。

###### GPU 分区的关键技术
1. vGPU（虚拟 GPU）技术：

- NVIDIA vGPU：这是 NVIDIA 提供的虚拟化技术，允许通过软件将一块 GPU 的资源分割为多个虚拟 GPU 实例。每个实例可以被一个虚拟机使用，类似于物理 GPU，但多个虚拟机可以同时使用一块物理 GPU。
- AMD SR-IOV（Single Root I/O Virtualization）：AMD 提供的虚拟化技术，允许物理 GPU 被分成多个虚拟功能 (VF)，这些功能可以分配给不同的虚拟机进行使用。
2. 硬件支持：

- GPU 分区依赖于硬件级别的支持，只有支持 SR-IOV 或 vGPU 的 GPU 才能实现分区。
- 例如，NVIDIA 的 Tesla 和 Quadro 系列 GPU，或 AMD 的 Radeon Pro 系列 GPU 支持这种虚拟化功能。
3. Hypervisor 支持：

- GPU 分区需要虚拟化平台（如 VMware、Hyper-V、KVM 等）的支持。这些虚拟化平台可以通过软件层管理 GPU 的资源分配，并确保多个虚拟机之间可以平滑共享 GPU 资源。

#### GPU Partitioning（GPU 分区）的主要优势包括:
GPU Partitioning（GPU 分区）的主要优势体现在灵活的资源管理、共享 GPU 的高效性以及多任务处理等方面。它特别适合虚拟化环境，尤其是在需要图形加速但不需要专用 GPU 的场景。以下是 GPU Partitioning 的几个主要优势：

1. 资源共享与灵活分配
- 多虚拟机共享同一 GPU：GPU 分区允许多个虚拟机（VM）共享同一块物理 GPU，而不是将整个 GPU 直通给单个虚拟机。这使得你可以在多个虚拟机之间灵活分配 GPU 资源，提升资源利用率。
- 按需分配 GPU 资源：可以根据每台虚拟机的需求，分配 GPU 的内存和计算能力。可以针对轻量级应用只分配一部分 GPU 资源，而不是分配整个 GPU。
2. 降低硬件成本
- 减少 GPU 采购需求：通过 GPU 分区，可以避免每个虚拟机都需要一块独立的物理 GPU，从而减少购买高性能 GPU 的需求和成本。共享 GPU 资源让你可以用一块 GPU 来处理多个虚拟机的工作负载。
- 更高性价比：尤其在一些企业或云计算场景，GPU Partitioning 可以最大化利用现有硬件设备，减少不必要的资源浪费。
3. 提升资源利用率
- 更高的 GPU 利用率：在传统的 GPU 直通模式下，一旦将 GPU 分配给某个虚拟机，其他虚拟机将无法使用该 GPU。而通过 GPU 分区，多个虚拟机可以同时使用同一块 GPU，从而提升 GPU 的利用率。
- 适合多任务工作负载：它特别适合需要 GPU 图形加速的多任务工作负载，例如多个轻量化的开发环境、桌面虚拟化或需要适度 GPU 加速的场景。
4. 虚拟化环境的高效支持
- 支持虚拟化的图形加速：传统虚拟机通常依赖 CPU 渲染图形，性能较差。而 GPU Partitioning 提供了硬件加速支持，提升了虚拟机的图形处理能力。
- 兼容性好：适用于大多数主流虚拟化平台（如 Windows 11 Hyper-V），无需特别的硬件调整，支持在现有基础设施上平滑集成 GPU 加速功能。
5. 适合轻量化图形处理任务
- 适合轻度图形渲染与计算任务：GPU Partitioning 非常适合那些不需要大量 GPU 资源的应用程序，比如视频会议、轻度的图形处理、桌面虚拟化等。
- 高效并行处理：在某些图形应用场景下（如虚拟桌面基础架构 VDI），多个用户可以同时使用共享 GPU 进行日常的图形加速任务，获得更高效的响应体验。
6. 动态调整与负载均衡
- 动态分配 GPU 资源：GPU Partitioning 支持动态调整资源分配。你可以根据每台虚拟机的负载和需求，增加或减少 GPU 资源，灵活应对业务变化。
- 负载均衡：通过合理的资源分配策略，可以更好地平衡不同虚拟机的图形工作负载，避免某一台虚拟机占用过多 GPU 资源。
7. 改善虚拟机的用户体验
- 更流畅的图形体验：对于桌面虚拟化（VDI）或远程桌面应用，GPU 分区可以显著提升虚拟机内的用户图形体验，使操作更流畅。
- 增强的图形处理能力：通过 GPU 分区，虚拟机可以获得比依赖 CPU 渲染更好的图形处理性能，从而提升应用程序的渲染速度和视觉效果。
8. 节能与效率提升
- 节能降耗：通过资源共享，减少了同时运行多个 GPU 的需求，从而降低了整体能耗。
- 减少硬件升级频率：GPU Partitioning 能有效延长现有硬件的生命周期，减少频繁的硬件升级需求。
###### 适用场景
- 虚拟桌面基础架构 (VDI)：多个虚拟桌面用户共享同一 GPU，加速桌面体验。
- 轻量级图形渲染：适合需要适度图形加速的轻量级应用，比如简单的 2D/3D 渲染任务。
- 软件开发与测试环境：开发者可以为多个测试环境分配一部分 GPU 资源，进行图形测试或模拟。
###### 总结
GPU Partitioning 的最大优势是灵活性与资源共享能力，它不仅可以有效提升硬件资源的利用率，还能显著降低硬件成本，尤其适合需要图形加速但不需要专用 GPU 资源的场景。

## 配置 Hyper-V GPU分区(将物理GPU共享给虚拟机):
#### 手动配置:
###### Windows 10 & Windows 11
1. 用 **管理员** 启动 Powershell 后,输入下面的命令,将虚拟机虚拟机和物理显卡关联
    使用下面命令之前,请先在Hyper-V 管理器 中查看虚拟机的名称后,将下面命令中 `你的虚拟机名称` 替换成 Hyper-V 管理器 中查看虚拟机的名称
    ```
    $vm = "你的虚拟机名称"
    ```
    ```
    Add-VMGpuPartitionAdapter -VMName $vm
    ```
    ```
    Set-VMGpuPartitionAdapter -VMName $vm -MinPartitionVRAM 80000000 -MaxPartitionVRAM 100000000 -OptimalPartitionVRAM 100000000 -MinPartitionEncode 80000000 -MaxPartitionEncode 100000000 -OptimalPartitionEncode 100000000 -MinPartitionDecode 80000000 -MaxPartitionDecode 100000000 -OptimalPartitionDecode 100000000 -MinPartitionCompute 80000000 -MaxPartitionCompute 100000000 -OptimalPartitionCompute 100000000
    ```
    ```
    Set-VM -GuestControlledCacheTypes $true -VMName $vm
    ```
    ```
    Set-VM -LowMemoryMappedIoSpace 1Gb -VMName $vm
    ```
    ```
    Set-VM -HighMemoryMappedIoSpace 32GB -VMName $vm
    ```
    举例: 假设虚拟机名称为: `Windows 11`



    命令如下:
    ```
    $vm = "Windows 11"
    ```
    ```
    Add-VMGpuPartitionAdapter -VMName $vm
    ```
    ```
    Set-VMGpuPartitionAdapter -VMName $vm -MinPartitionVRAM 80000000 -MaxPartitionVRAM 100000000 -OptimalPartitionVRAM 100000000 -MinPartitionEncode 80000000 -MaxPartitionEncode 100000000 -OptimalPartitionEncode 100000000 -MinPartitionDecode 80000000 -MaxPartitionDecode 100000000 -OptimalPartitionDecode 100000000 -MinPartitionCompute 80000000 -MaxPartitionCompute 100000000 -OptimalPartitionCompute 100000000
    ```
    ```
    Set-VM -GuestControlledCacheTypes $true -VMName $vm
    ```
    ```
    Set-VM -LowMemoryMappedIoSpace 1Gb -VMName $vm
    ```
    ```
    Set-VM -HighMemoryMappedIoSpace 32GB -VMName $vm
    ```

2. 将宿主机的驱动复制到虚拟机中
    - 在您复制NVIDIA驱动之前,您需要了解,每次更新驱动之后,更新后的驱动目录名称都会改变.
    - 如何查找宿主机的Nvidia驱动目录?使用命令 ` Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\nvlddmkm" | Select-Object ImagePath `

    (仅供参考)我的PC输出如下:
    ```PowerShell
    PS C:\Windows\system32> Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\nvlddmkm" | Select-Object ImagePath

    ImagePath
    ---------
    \SystemRoot\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_ea1f658f0e22227d\nvlddmkm.sys
    ```
    从上面的输出信息可以得知,我PC宿主机的驱动目录(我们需要复制的目录)为:`\SystemRoot\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_ea1f658f0e22227d` ,
    其中`\SystemRoot\`是指Windows根目录,`nvlddmkm.sys`只是驱动目录中的文件,因为我的Windows安装在磁盘 `C`, 因此`\SystemRoot\` 真是路径为: `C:\Windows`,我需要复制的是`nv_dispi.inf_amd64_ea1f658f0e22227d`目录.
    有两种方法
    - 绝对路径
    ```
    C:\Windows\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_ea1f658f0e22227d
    ```
    - 路径变量(推荐)
    ```
    %SYSTEMROOT%\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_ea1f658f0e22227d
    ```

    虚拟机驱动路径：
    ```
    %SYSTEMROOT%\System32\HostDriverStore\FileRepository\
    ```

3. 将宿主机的`nvapi64.dll`(NVIDIA 显卡和驱动程序关联的动态链接库 (DLL) 文件)复制到虚拟机中
宿主机`nvapi64.dll`路径:
```
%SYSTEMROOT%\System32\nvapi64.dll
```
虚拟机`nvapi64.dll`路径:
```
%SYSTEMROOT%\System32\nvapi64.dll
```

#### 使用 PowerShell脚本
脚本作者: ThioJoe
脚本链接: https://gist.github.com/ThioJoe/96d911749c18f9d64e2c60cdc11fa62f
经过测试,使用前需要注意的是:
1. 该脚本从宿主机复制的驱动是 `nv_` 开头的驱动,如果笔记本,有可能是`nvmii.`开头的驱动.因此,你需要对脚本进行修改,将 `nv_` 替换成 `nvmii.`
    - 使用 `Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\nvlddmkm" | Select-Object ImagePath`查询驱动路径,确认`\SystemRoot\System32\DriverStore\FileRepository\`后面是`nv_`或`nvmii.`
    - 如果是`nvmii.`,修改`.ps1`脚本
2. 如果你更新过驱动,`%SYSTEMROOT%\System32\DriverStore\FileRepository\`目录下可能有一个或多个 `nv_`或`nvmii.`开头的目录,如果有多个,说明存在旧驱动,可以手动删除.原因是:脚本会复制所有`nv_`(默认) 或`nvmii.`(手动修改过)的驱动,旧驱动是不必要的,也会浪费时间并占用系统资源.