admin管理员组文章数量:1122853
微软服务器dda,Hyper
年初的时候老板火急火燎撒钱买了一台四路1080Ti服务器给实验室用作深度学习使用,结果火急火燎地买回来才发现很多深度学习框架对多GPU支持并不好,于是只能分开使用。想我也是经历过共用服务器的混乱,于是提议建立四个虚拟机,然后把整块物理GPU直接分配给各自虚拟机互不干扰,因为之前偶然看到过从Windows Server 2016开始,微软为Hyper-V虚拟机加入了物理设备直通(Discrete Device Assignment, DDA)的功能,允许虚拟机完全控制宿主机上的某些硬件(包括但不限于GPU,网络适配器等)。一开始以为应该也挺简单的,但实际上还是踩了很多坑才最终弄好。
关于Discrete Device Assignment的详细信息,可以查看微软虚拟化博客四连:
本文以这些相关官方博文为基础记录了直通显卡的一般流程,适合对DDA技术感兴趣的朋友入门尝鲜。此外,我封装了一个简单的带GUI的工具:
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为正常的可用状态。
版权声明:本文标题:微软服务器dda,Hyper 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/biancheng/1701360253a385219.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论