GPU虚拟机创建时间深度优化
桔妹导读:GPU虚拟机实例创建速度慢是公有云面临的普遍问题,由于通常情况下创建虚拟机属于低频操作而未引起业界的重视,实际生产中还是存在对GPU实例创建时间有苛刻要求的业务场景。本文将介绍滴滴云在解决该问题时的思路、方法、并展示最终的优化成果。
从公有云服务商那里购买过虚拟主机的资深用户,一般会发现这么个规律:创建一台CPU虚拟主机是比较快的,但是要创建一台包含GPU卡的虚拟主机通常需要等比较长的时间,整个创建过程短则数十秒钟,长则数分钟。对于绝大多少的用户来说,虚拟主机的创建时间长一点对他们影响并不大,因为创建虚拟机属于相对低频操作。但是也会有一些特定的用户由于其业务场景交互性比较强,会对虚拟主机的创建时间有相对苛刻的要求,因为过长的创建时间会导致其业务用户体验很差。本文将从虚拟化的角度来介绍GPU虚拟主机创建时间长背后的原因,以及相关的优化方法。
通过分析Libvirt, QEMU以及Guest 内的相关日志及对应的时间戳,可以获取GPU虚拟主机在创建过程中的耗时情况,这里我们主要关心几个关键的时间点: a) Libvirt 开始创建QEMU 进程;b) Libvirt 执行 Resume启动VCPU ; c) Guest kernel 打印第一条日志. 在本文中,我们把a和 b 之间的时间间隔称为QEMU初始化时间, 把b 和c 之间的时间间隔称为 BIOS执行时间。以下数据是在滴滴云的线上环境中采集到的创建一台包含8个CPU核虚拟机实例的相关数据:
从上面的数据可以看到,对于规格相同的虚拟机实例,带1块P40卡的GPU实例相比同规格的CPU实例在QEMU初始化及BIOS执行部分的时间都明显要长, 在带4块P40卡以及更大内存规格的场景下,需要的时间会进一步拉长。通过实验我们发现在主机配置和GPU卡型号确定的前提下,GPU实例的创建时间长短主要取决于两个因素:虚拟机的内存大小和GPU卡的数量。
为什么GPU实例的创建过程要比CPU实例的创建过程耗时长?多消耗的时间到底花在哪里?要搞清楚原因需要深入的分析,比较直观的办法就是通过perf采样来生成火焰图,以此来分析虚拟机在创建过程中的热点函数。下图是在滴滴云环境里抓取到的GPU虚拟机启动过程中QEMU进程的火焰图。
通过对代码调用关系的分析,可以得知热点发生在系统分配内存和对内存页面清零的过程中,是由QEMU中的vfio_dma_map函数在执行VFIO_IOMMU_MAP_DMA ioctl 系统调用所触发,该调用会Pin住所有分配给VM当做RAM使用的内存。在Pin 内存的过程中,如果虚拟内存对应的物理页面尚未分配,会先进行物理内存分配并对内存页面内容进行清零。在Linux kernel 中,对分配给应用程序的内存进行清零主要是基于安全方面的考虑,避免Host 内存中的内容泄漏给用户空间的应用程序。这里之所以要将内存Pin 住,目的是为了保证IOMMU IO页表和 host HVA->HPA 映射的一致性,否则Guest 内设备的DMA操作可能会访问到错误的内存页面。
VFIO DMA 映射处理慢可以在一定程度上解释为什么内存的大小和GPU卡的数量会影响到GPU实例的创建时间。虚拟机实例内存规格越大,需要映射和Pin住的内存量也就越大,相关处理的耗时和内存量成正比。另外GPU卡上通常会包含一块比较大的MMIO区域,对MMIO的映射也会耗费较多的时间,卡的数量越多,耗时就会越长。相比之下,CPU实例的创建过程没有VFIO DMA 映射的相关处理流程,因此会比较快。
针对以上的热点,有什么办法可以消除或者缓解呢?已经有业内的同行们提到过这个问题并给出了对应的解决方案,其思路是对分配给VM 用作RAM使用的内存区域做一个标记,在内核中跳过对标记的内存页面进行清零,而将清零的动作留给QEMU来做,在QEMU 中可以利用多线程以及更高效的指令进行清零动作,从而加速Pin内存的过程。该方案的缺陷主要有两点: 一是存在安全性风险,其他应用程序可以利用设定的标记来窥探host 内存中的信息;二是在VM实例的VCPU个数比较少的情况下,优化效果不是很好。
我们采用了另外一种方案,通过修改Host kernel的内存管理部分, 我们实现了一种对Host 上空闲物理内存提前进行清零的机制,清零动作可以在系统空闲的时候进行,当某个内存页面被清零后,将其对应的 struct page 进行标记,这样在需要对内存进行清零的时候,可以通过检查该标记来判断是否要执行清零动作,如果清零的标记已经被设置,就可以跳过清零的步骤。该方案避免了上述方案中的两个主要问题,同时还有其它方面的好处,主要包括以下几点:a.可以提高缺页异常处理效率,尤其是透明大页的缺页异常处理效率;b. 可以加速需要Pin内存及需要通过mlock 来锁住内存的应用场景,例如使用RDMA, QAT 硬件加速等场合;c. 可以加速内核中其他需要对内存进行清零的场景。相关补丁的RFC版本,我们已经提交到了Linux kernel 社区。
另一个加速Pin内存的有效方法是采用大页,通过开启透明大页可以显著减少缺页处理的调用次数并加速Pin内存的过程。下图展示了开启透明大页以及启用空闲内存预清零机制对GPU实例创创建时间的影响。
以上的数据表明,在开启透明大页以及空闲内存预清零功能后,可以显著的的优化QEMU的初始化时间,但是BIOS部分的耗时依然偏长。通过进一步的分析我们发现主要的时间消耗还是在VFIO 映射DMA的处理过程当中,主要有几个方面的原因:a. 映射DMA Pin内存需要逐页查询页表,开销较大;b. QEMU 存在对部分IOVA区域的反复映射及解除映射的操作。于是我们尝试在这两个方向上进行优化,通过采用批量处理的方法减少查询页表的开销,另外在QEMU中加入VFIO DMA映射区域的管理,有效的规避了效率低下的反复映射及解除映射操作,最终大幅度降低了VFIO DMA映射的时间消耗。
在解决完上述问题后我们并没有止步,对虚拟机实例创建过程中的可优化的其它地方,我们也做了相关的处理,例如关闭BIOS boot menu ,优化VFIO PCI 设备reset 的流程,去掉对GPU实例来说不必要的操作,最终将GPU实例创建过程中虚拟化部分的时间开销减少了90%以上,下面这张图展示了单卡小内存规格实例优化前后的耗时对比:
大内存规格和多GPU卡的效果更加显著,时间减少了95%以上,相关数据如下图:
经过上述的优化,目前在滴滴云上创建一个GPU实例的速度比优化前显著加快,甚至比优化前创建一个CPU实例的速度还要快,如果用户对GPU实例的创建速度有比较强的需求,欢迎到滴滴云上进行体验。
团队介绍
滴滴云平台事业群滴滴内核团队致力于为公司各种业务提供底层系统软件支撑,负责公司线上服务器Linux操作系统内核的研发并维护虚拟化相关的核心组件。团队针对各个业务的需求,在虚拟化、业务混部、资源隔离、系统性能优化等领域均有广泛深入的研究,在公有云、弹性云等业务线都有相关的产品。
作者介绍
专注于系统虚拟化研究,负责解决滴滴云底层虚拟化相关技术问题。曾就职于Intel 开源软件中心虚拟化组,具备丰富的底层系统软件开发经验。
延伸阅读
内容编辑 | Charlotte
联系我们 | DiDiTech@didiglobal.com
本文由博客群发一文多发等运营工具平台 OpenWrite 发布
GPU虚拟机创建时间深度优化的更多相关文章
- shell-计算虚拟机创建时间
因为要验证虚拟机创建时间,所以写了下面一个脚本 #!/bin/bash ################################################################ ...
- TVM 优化 ARM GPU 上的移动深度学习
TVM 优化 ARM GPU 上的移动深度学习 随着深度学习的巨大成功,将深度神经网络部署到移动设备的需求正在迅速增长.与桌面平台上所做的类似,在移动设备中使用 GPU 既有利于推理速度,也有利于能源 ...
- Mali GPU OpenGL ES 应用性能优化--基本方法
1. 经常使用优化工具 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTXlBcnJvdw==/font/5a6L5L2T/fontsize/400/fil ...
- GPU加速:宽深度推理
GPU加速:宽深度推理 Accelerating Wide & Deep Recommender Inference on GPUs 推荐系统推动了许多最流行的在线平台的参与.随着为这些系统提 ...
- GPU上创建目标检测Pipeline管道
GPU上创建目标检测Pipeline管道 Creating an Object Detection Pipeline for GPUs 今年3月早些时候,展示了retinanet示例,这是一个开源示例 ...
- 深度优化LNMP之PHP (转)
深度优化LNMP之PHP PHP缓存加速介绍 1.操作码介绍及缓存原理 当客户端请求一个php程序时,服务器的PHP引擎会解析该PHP程序,并将其编译为特定的操作码文件(Operate ...
- Citrix 服务器虚拟化之六 Xenserver虚拟机创建与快照
Citrix 服务器虚拟化之六 Xenserver虚拟机创建与快照 在Xenserver上可以创建Windows和Linux等虚拟机,Xenserver支持大部分的主流操作系统,可以使用 XenCe ...
- supervessel-免费云镜像︱GPU加速的Caffe深度学习开发环境
开发环境介绍 在SuperVessel云上,我们为大家免费提供当前火热的caffe深度学习开发环境.SuperVessel的Caffe有如下优点: 1) 免去了繁琐的Caffe环境的安装配置,即申请即 ...
- 百度APP移动端网络深度优化实践分享(二):网络连接优化篇
本文由百度技术团队“蔡锐”原创发表于“百度App技术”公众号,原题为<百度App网络深度优化系列<二>连接优化>,感谢原作者的无私分享. 一.前言 在<百度APP移动端网 ...
随机推荐
- Python os.readlink() 方法
概述 os.readlink() 方法用于返回软链接所指向的文件.可能返回绝对或相对路径.高佣联盟 www.cgewang.com 在Unix中有效 语法 readlink()方法语法格式如下: os ...
- PHP mysqli_thread_id() 函数
返回当前连接的线程 ID,然后杀死连接: <?php 高佣联盟 www.cgewang.com // 假定数据库用户名:root,密码:123456,数据库:RUNOOB $con=mysqli ...
- hadoop 莫名奇妙产生分区 0000 00001 00002
使用 multipleOutputs.write()时候,莫名奇妙的产生好多分区 job.setCombinerClass(ClassifierReduce.class); //注释掉该句 就不会 ...
- Linux输出缓存你知道多大吗?
今天看到这个代码很简单,就是验证一下Linux系统的输出缓存大小.当 猜一下这个代码的输出: #include <stdio.h> #include <string.h> #i ...
- Meow 攻击会删除不安全(开放的)的Elasticsearch(及MongoDB) 索引,然后建一堆以Meow结尾的奇奇怪怪的索引(如:m3egspncll-meow)
07月29日,早上照例一来,先连接Elasticsearch查看日志[禁止转载,by @CoderBaby],结果,咦,什么情况,相关索引被删除了,产生了一堆以Meow开头的奇奇怪怪的索引,如下图: ...
- 一文说通C#中的异步编程补遗
前文写了关于C#中的异步编程.后台有无数人在讨论,很多人把异步和多线程混了. 文章在这儿:一文说通C#中的异步编程 所以,本文从体系的角度,再写一下这个异步编程. 一.C#中的异步编程演变 1. ...
- Java实现短信验证码
前言 本人使用的是阿里短信服务,一开始尝试了许多不同的第三方短信服务平台,比如秒滴科技.梦网云通讯.当初开始为什么会选择这两个,首先因为,他们注册就送10元钱(#^.^#),但是后来却发现他们都需要认 ...
- 【av68676164(p55-p58)】 Intel CPU和Linux内存管理
7.4.1 Intel CPU物理结构 https://www.cnblogs.com/megachen/p/9768115.html x86实模式 实模式 20位:1M内存空间 地址表示方式:段地址 ...
- css实现折扇效果
总结思路: 1.首先进行结构的书写 <div class="box"></div> 2.要进行图片的重叠要用到position定位,需要重叠的元素及子元 ...
- SqlServer 版本号
RTM (no SP) SP1 SP2 SP3 SP4 SQL Server 2014 codename Hekaton 12.00.2000.8 SQL Server 2012 ...