Hyper

您所在的位置:网站首页 虚拟机调用显卡和显卡直通的区别 Hyper

Hyper

2024-07-15 10:30| 来源: 网络整理| 查看: 265

年初的时候老板火急火燎撒钱买了一台四路1080Ti服务器给实验室用作深度学习使用,结果火急火燎地买回来才发现很多深度学习框架对多GPU支持并不好,于是只能分开使用。想我也是经历过共用服务器的混乱,于是提议建立四个虚拟机,然后把整块物理GPU直接分配给各自虚拟机互不干扰,因为之前偶然看到过从Windows Server 2016开始,微软为Hyper-V虚拟机加入了物理设备直通(Discrete Device Assignment, DDA)的功能,允许虚拟机完全控制宿主机上的某些硬件(包括但不限于GPU,网络适配器等)。一开始以为应该也挺简单的,但实际上还是踩了很多坑才最终弄好。

关于Discrete Device Assignment的详细信息,可以查看微软虚拟化博客四连:

Description and background

Machines and devices

GPUs

Guests and Linux

本文以这些相关官方博文为基础记录了直通显卡的一般流程,适合对DDA技术感兴趣的朋友入门尝鲜。此外,我封装了一个简单的带GUI的工具:

https://github.com/chanket/DDA/releases

GUI工具测试系统为Windows Server 2016,据评论区反馈,最新的Windows Server 2019不能使用该工具。

显卡直通与RemoteFX的区别

DDA直通显卡是将整张显卡的控制权限移交给虚拟机,而类似RemoteFX技术则是将宿主机上的显卡虚拟化后为虚拟机提供一定的3D加速支持。简单来说:

DDA虚拟机中看到的是一张物理显卡,RemoteFX虚拟机中看到的是一张虚拟化后的显卡; DDA虚拟机(理论上)可以使用物理显卡的任何特性,包括OpenCL、CUDA等等,而RemoteFX则不支持; RemoteFX可以为虚拟机提供比较完备的3D加速功能,而DDA即便直通了显卡也不一定有完整的3D加速; 等等。 要求

物理设备直通对系统的硬件和软件都有一定的要求,除了需要宿主机的操作系统为Windows Server 2016 TP4以上版本外,还需要以下要求:

主板固件支持。你的BIOS(或UEFI)必须支持:SR-IOV、Access Control Service(ACS)等功能。根据主板型号的不同,有的可能需要你在在BIOS中手动开启,有的可能默认就已经支持,有的则可能需要更新BIOS版本。例如,在超微X10DRG-Q主板上,我就曾因为主板BIOS版本为2.0a而无法启用ACS,这个问题最后通过更新到2.0b得到解决。 设备支持。并非所以类型的设备都可以被直通到虚拟机中。具体可以通过微软提供的这个脚本来查询。此外,部分无良硬件厂商可能会刻意限制设备出现在虚拟机中,例如,英伟达在驱动层面对GeForce系列GPU做出了限制,当检测到虚拟化环境时,设备将抛出错误码43而拒绝工作。然而,只要你按照Github上开源的这个脚本屏蔽官方驱动的虚拟环境检测,就可以发现GeForce显卡可以非常完美地工作在虚拟机中。更新:2021年4月更新的英伟达驱动据说移除了GeForce显卡的直通限制,待验证。 虚拟机设置。一个虚拟机要接收直通的设备,其设置上有两点额外的要求。首先,如果虚拟机启用了动态内存,那么需要满足启动RAM==最小RAM;其次,虚拟机的“自动停止操作”必须为“强行关闭虚拟机”(新创建的虚拟机的默认设置为“保存虚拟机状态”)。

微软没有提供DDA的相关操作的GUI工具,关键操作只能通过PowerShell完成,这可能对不太熟悉Powershell的用户来说比较煎熬。

下面,我们以Tesla V100为例,将其从宿主机直通到目标虚拟机Test中。

步骤一:获取设备路径(Location Path)

设备路径在物理设备直通的过程中相当于设备的唯一描述符。下面的Powershell展示了如何获取名称以NVIDIA开头的设备的设备路径。

#获取所有名称以NVIDIA开头的设备 $pnpdevs = Get-PnpDevice -PresentOnly | Where-Object {$_.FriendlyName -like "NVIDIA*"} #输出LocationPath foreach ($pnpdev in $pnpdevs) { $locationpath = ($pnpdev | get-pnpdeviceproperty DEVPKEY_Device_LocationPaths).data[0] $pnpdev.FriendlyName + ": " + $locationpath }

在我的机器上,可以得到下面的输出:

NVIDIA Tesla V100-SXM2-16GB: PCIROOT(0)#PCI(0300)#PCI(0000)#PCI(0C00)#PCI(0000) NVIDIA Tesla V100-SXM2-16GB: PCIROOT(0)#PCI(0300)#PCI(0000)#PCI(0800)#PCI(0000) NVIDIA Tesla V100-SXM2-16GB: PCIROOT(80)#PCI(0200)#PCI(0000)#PCI(0800)#PCI(0000) NVIDIA Tesla V100-SXM2-16GB: PCIROOT(80)#PCI(0200)#PCI(0000)#PCI(0C00)#PCI(0000)

这个过程也可以通过设备管理器完成,如图所示:

步骤二:禁用设备

要被直通的物理设备将会被虚拟机独占使用,因此,操作系统需要确保宿主机没有其它应用在使用被直通的设备,因此在直通前禁用设备。

我们可以使用Disable-PnpDevice命令,通过设备的InstanceId来禁用设备。例如,在上文Powershell中获取$pnpdev对象后,继续执行:

disable-pnpdevice -InstanceId $pnpdev.InstanceId -Confirm:$false

这个过程同样可以通过设备管理器完成,如图所示:

步骤三:下线(Dismount)设备

这一步操作会将已经禁用的设备从操作系统中移除,使其变成可分配的状态。这一步只能通过Powershell完成。根据上面获得到的设备路径(Location Path),例如,"PCIROOT(0)#PCI(0300)#PCI(0000)#PCI(0C00)#PCI(0000)",运行下面的命令:

Dismount-VmHostAssignableDevice -locationpath "PCIROOT(0)#PCI(0300)#PCI(0000)#PCI(0C00)#PCI(0000)" -force

这一步是最可能出现错误的。许多硬件上的不兼容都会在这个步骤报错。

成功执行此步操作后,宿主机上的设备管理器将无法查看到该设备。

步骤四:分配设备

假设前面的步骤都已完成,这个时候就已经可以将下线后的设备分配给虚拟机了。这一步依然只能通过Powershell完成。将GPU分配到名称为Test的虚拟机中的命令如下所示:

Add-VMAssignableDevice -LocationPath "PCIROOT(0)#PCI(0300)#PCI(0000)#PCI(0C00)#PCI(0000)" -VMName Test

如果到这一步依然没有任何错误,那么设备已经成功直通到了虚拟机上。你可以通过下面的Powershell检查:

Get-VMAssignableDevice -VMName Test

在我的机器上,可以得到下面的输出:

InstanceID : PCIP\VEN_10DE&DEV_1DB1&SUBSYS_121210DE&REV_A1\6&3D280D5&0&00600018 LocationPath : PCIROOT(0)#PCI(0300)#PCI(0000)#PCI(0C00)#PCI(0000) ResourcePoolName : Primordial Name : 虚拟 PCI Express 端口设置 Id : Microsoft:C3B8CA0E-F6DA-417C-B6D6-DD9D68F7D899\EAEE9BF9-B29B-4D2E-970B-325F02812E83 VMId : c3b8ca0e-f6da-417c-b6d6-dd9d68f7d899 VMName : Test VMSnapshotId : 00000000-0000-0000-0000-000000000000 VMSnapshotName : CimSession : CimSession: . ComputerName : TRAIN IsDeleted : False VMCheckpointId : 00000000-0000-0000-0000-000000000000 VMCheckpointName : GPU额外步骤一:合并缓存写入

对于GPU相比于一般的外部设备速度很快,这使得如果我们允许对CPU合并对GPU显存的写入操作以提升性能。以Test虚拟机为例,运行下面的Powershell:

Set-VM Test -GuestControlledCacheTypes $true GPU额外步骤二:扩大内存映射IO空间(Memory Mapped IO Space)大小

GPU需要的MMIO空间通常较大,当一个虚拟机分配到的设备所需要的MMIO空间综合超过了Hyper-V为其默认提供的大小时,在虚拟机操作系统中就会提示“没有足够的系统资源”的错误。

你可以在设备管理器右键设备-属性中看到设备所需的MMIO空间,如图所示:

根据内存范围,我们可以算出一张V100所需的MMIO大小为16MB+16384MB+32MB,其中,32位地址空间内需求16MB,64位地址空间内需求16384MB+32MB=16416MB。目前一个新建的Hyper-V虚拟机默认只为32位和64位地址空间分别提供了128MB和512MB的MMIO空间大小,这导致V100直接分配到虚拟机中是无法使用的。

32位和64位地址空间的MMIO大小可以通过下面的Powershell来分别修改,以Test虚拟机为例:

Set-VM Test -LowMemoryMappedIoSpace upto3000MB Set-VM Test -HighMemoryMappedIoSpace upto33000MB

在这里,我为V100保留了17000MB的HighMemoryMappedIoSpace,保持LowMemoryMappedIoSpace不变。

结果展示

在虚拟机中安装NVIDIA驱动后,可以看到V100为正常的可用状态。

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3