Page 47 - 《软件学报》2020年第10期
P. 47
李鼎基 等:基于跨虚拟机零下陷通信的加速器虚拟化框架 3023
一台服务器上的内存而无需任意一方操作系统参与 [25] ,意味着可以支持零拷贝(zero-copy)从而降低延迟以及
CPU 的性能损失,RDMA 的驱动会直接复用用户态进程的内存来进行传输且完全无需 CPU 参与.基于 RDMA
的通信方式有着优秀的性能与较低的延迟,然而,由于需要购置专用的 RDMA 网卡并且安装专用的驱动,在运维
方面会产生一笔较大的成本,降低了该类方案的可用性.
本节以 Caffe 中 Neuron Layer 测试为例,对于 API 转发模式的虚拟化方案进行了一系列测试分析,该测试用
例在一次运行过程中调用了超过 110 万次、共计 40 种不同的 CUDA API,表 1 列出了调用频率前 5 的 API 明
细.测试之前,本文首先对 GVirtuS 进行了扩展和优化,将其以 VM-VM 模式部署在两台处于同一物理服务器的
虚拟机中,通信模块以共享内存作为参数拷贝的载体,TCP/IP 作为参数拷贝完成的通知机制.
Table 1 List of APIs frequently called during Neuron Layer testcase
表 1 Neuron Layer 测试中被高频调用的 CUDA API 列表
CUDA API 名称 调用次数
cudaMemcpy 290 122
curandSetPseudoRandomGeneratorSeed 268 537
curandSetGeneratorOffset 268 536
cudaLaunch 142 394
cudaPeekAtLastError 127 246
接下来,本文对于 Caffe 中 Neuron Layer 测试用例的 API 转发流程进行了耗时分析,将虚拟化时的一次
CUDA API 调用流程划分为以下 3 个部分:(1) 额外
内存拷贝耗时,包含数据与共享内存间序列化与反
序列化的时间开销;(2) 通知机制耗时,包含虚拟机
之间通知对方共享内存可用的时间开销;(3) 原生
API 执行耗时,其中只有原生 API 执行耗时是不可避
免的有效工作时间,剩余的耗时均属于通信模块的
额外性能开销.经过测试,各部分平均耗时占比如图
2 所示,测试中 API 调用的总时间为 283 750 417 817
Fig.2 Analysis of the average time cost of
个 cycle,可以看到,额外性能开销占整个流程耗时的
Neuron Layer in GVirtuS
88%以上(250 528 017 067cycle),其中,额外内存拷贝
图 2 GVirtuS 中 Neuron 测试用例平均耗时占比分析
耗时仅占不到 1%(1 910 231 774cycle),通知机制的
耗时占比高达 87%(248 617 785 293cycle),因此,现有虚拟化系统中的通知机制是造成性能问题的最大瓶颈,也
是本文有针对性的要进行优化的重点.
2.2 CPU 利用率的问题
在原生物理服务器的环境下,调用加速器的过程中一个进程的 CPU 有效运行时间 T有效可以主要划分为两
部分:(1) 在用户态运行应用程序功能的时间;(2) 在内核态运行驱动程序与加速器交互的时间,其余时间由于
没有产生真正有用的结果均可以视作无效运行时间 T 无效.因此,在加速器虚拟化的情况下,衡量一个虚拟化框架
性能和效率的重要指标就是虚拟化后 CPU 的有效运行时间占总运行时间的比例为 T 有效/(T 有效+T 无效).
在理想情况下,虚拟化后的比例和原生物理环境下的比例相同,即虚拟化没有造成额外的性能开销.本节所
述的基于 API 转发的方案均使用的是主动式的交互方式,不论是通过网络还是共享内存通信,都需要服务端与
客户端双方的 CPU 协助完成,而实际有效运行时间只有客户端 CPU 执行应用程序以及服务端 CPU 执行驱动
程序的时间.为降低调度导致的延迟,正常情况下服务端与客户端都会被绑定在不同的物理 CPU 上,如图 3 所示,
虚拟化时一次转发调用所耗费的 CPU 资源会是原生物理环境的 2 倍以上.
本节使用了 Linux 操作系统内置的 time 命令,利用上一节中的测试用例在原生物理环境与 GVirtuS 虚拟化
环境下分别测量了 CPU 利用率.如表 2 所示,原生物理环境下只占用了 1 个 CPU,利用率高达 97.28%,而 GVirtuS
环境下占用了 2 个 CPU 且利用率分别仅为 46.61%和 38.52%.