Page 55 - 《软件学报》2020年第10期
P. 55

李鼎基  等:基于跨虚拟机零下陷通信的加速器虚拟化框架                                                      3031


         4.4   代理执行时的扩展页表缺页处理
             使用 QEMU-KVM 虚拟化平台时,每个客户虚拟机从主机操作系统的角度来看,本质上都是一个可以利用
         KVM 内核模块进行加速的用户态 QEMU 进程              [28] ,所以每个虚拟机的内地址空间本质上都是对应 QEMU 进程
         的地址空间.一个正常运行的虚拟机如果触发了扩展页表的缺页错误,CPU 会发生原因为 EPT violation 的虚拟
         机下陷,KVM 会根据缺页错误的 GPA 在当前 QEMU 进程的地址空间中进行处理.处理过程中,Linux 内核会首
         先依据名为 current 的 per-CPU 变量来获取当前 CPU 上运行着的进程描述符(task_struct 结构体),其中存放着与
         当前 QEMU 进程绑定的内存描述符(mm_struct 结构体),然后利用 Linux 内核的内存管理相关函数为该内存描
         述符分配实际的物理内存,最后给扩展页表补充 GPA 到 HPA 的映射.
             代理执行时如果触发了扩展页表缺页错误,下陷后 KVM 识别到的当前进程身份仍然是客户端虚拟机的
         QEMU 进程,因此 KVM 会在客户端 QEMU 进程的地址空间中分配新的内存,并向客户端虚拟机的扩展页表中
         添加映射.而实际上缺页错误发生在服务端虚拟机地址空间中,正确的操作应该是给服务端的 QEMU 进程分配
         新的内存并添加扩展页表映射.因此,本系统修改了 KVM 的 EPT violation 处理函数,在发生缺页错误下陷后会
         首先判断当前是否正在代理执行.如果是,则会暂时将当前 current 变量存储并替换为初始化时记录的服务端
         QEMU 进程的进程描述符,这样在内存分配和扩展页表映射时 KVM 的操作对象均为服务端虚拟机,待完成后
         再将 current 变量恢复.由于服务端虚拟机一直处于冻结状态,所以上述操作不会有数据冲突(data race)的风险.
         4.5   亟待完善的部分 CUDA 特性

             对于 CUDA 绑定内存特性(pinned memory)等由于驱动的闭源性未能支持,对于 CUDA 多流(stream)操作等
         异步 API 暂时会被转化为同步版的 API 调用,因此对 Host 和 Device 间的内存拷贝性能会有一定的影响.不过,
         未完全实现的部分与本文的设计是正交的,并不会妨碍证明本加速器虚拟化框架设计带来的大幅度性能提升.

         5    系统评测

             为了测试原型系统的性能,本文使用了一台支持 VMFUNC 硬件虚拟化特性的 Intel Haswell-E 消费级服务
         器作为测试平台,该测试平台的主要软/硬件配置见表 3.本节按照测试的粒度从小到大主要分为 3 个部分,将
         PCI 直通的虚拟化方案作为最高性能的基准线(baseline).

                                         Table 3   Testbed configuration
                                           表 3   测试平台配置信息
                                  名称                   Model/Version
                                  CPU          Intel i7-5930K@3.5GHz (6 核 12 线程)
                                  内存                40GB DDR4 2133MHz
                                  GPU          NVIDIA Quadro GV100 (32GB HBM2)
                                操作系统              Ubuntu 19.10 (Eoan Ermine)
                                内核版本                Linux Kernel 4.19.56

             为了对比目前公开可用的 GPU 虚拟化解决方案,本文选取了具有代表性的开源方案 GVirtuS 作为对照,由
         于最新的 GVirtuS 支持的 CUDA API 仍然非常有限,本文对 GVirtuS 的源码进行了补充,使其支持与本原型系统
         同样多的 CUDA API.此外,由于 GVirtuS 的通信模块对于 VM-VM 模式下的虚拟化仅支持 TCP/IP 方式,在 API
         转发时额外的内存拷贝开销较大.本文为 GVirtuS 的通信模块添加了与原型系统相同的共享内存方式,消除了
         两个系统在内存拷贝开销上的差异,既提升了 GVirtuS 系统的性能,又保证了性能测试的公平性.
             过去的大部分原型系统仅仅支持了小部分的 CUDA API,选用的测试用例与现实场景中的应用程序相差较
         大,无法全面地反映出系统真实的性能表现.本文选取了流行的 Caffe                    [29] 作为基准测试程序,Caffe 是一个用 C++
         编写的深度学习框架,由于其清晰、高效的优点在深度学习领域                       [30] 中被广泛使用.
   50   51   52   53   54   55   56   57   58   59   60