在上期,我们说到,益民食品厂的一名青年工程师利用自己所学的电机学的知识,在电网解体的情况下,抢修工厂供电成功。
其实,这就是电气化带来的价值——动力系统的鲁棒性提升。
小H脑海里出现了一个问题:在电气化实现以前,工厂的动力是哪里来的呢?为了解决这个问题,小H一大早就跑去图书馆,但翻了半天也没有找到讲这个问题的资料。小H觉得又困又累,趴在桌上休息一会。
小H再起身的时候,发现自己在一个巨大的工厂车间里,车间的中央有一根粗大的轴,它的周边有很多皮带、齿轮和离合器等机械传动机构也在这根巨大的轴一起飞速旋转。
从车间的另一头传来巨大的轰鸣声,滚滚黑烟混合着白色的蒸汽扑面而来,尖锐的蒸汽声震撼着每个人的耳膜。这是一台改进后的蒸汽机,通过离心式调速器来控制速度。调速器上的两个球随着速度的增加而上升,并带动机械装置操控蒸汽机的风门,来实现速度的反馈控制。
突然,调速器的一个臂断了,风门被开到最大,蒸汽机的运转速度越来越快,蒸汽的爆鸣声也越来越尖锐……小H想逃跑,但双脚似乎被束缚住一样跑不动。小H突然想尿尿,又跑不动,心一急睁开了眼睛。
小H发现自己还趴在图书馆的桌前,快到闭馆时间了。原来,小H又因为看书而犯困睡着了,并且差点尿裤子。
小H梦里看见的就是机械时代工厂的动力车间,蒸汽机通过动力主轴给整个工厂提供动力,各个车间通过皮带、齿轮或离合器装置来从动力主轴上取得自己所需的动力。这样的系统的可靠性和安全性都不高,也难以精确地控制给不同车间输送的动力功率。用计算机领域的术语,就是缺乏QoS(Quality of Service)的保障。
电气化比起机械化来,最大的变化就是,动力的QoS保障更好,代表了更先进的生产力,因此,列宁才有了“共产主义就是苏维埃加全国电气化”的论断,而电机和无线电方面的人才也成为了建设社会主义的栋梁。
在计算机领域,QoS也是一个让科学家和工程师们皓首穷经的问题。A云的cGPU,就是因为在GPU虚拟化的QoS方面做得不够好,而难以被私有化用户所接受。
要实现GPU的QoS,就需要能够有效地切换不同租户的任务,这样才可以保证给任何租户分配多少资源,租户可得的就是多少资源,而不被其他租户所挤占。
在CPU程序中,这种任务切换是早已在操作系统内核内部实现的功能,任何一本《操作系统》教科书都会详解任务切换的原理和实现:在系统的时钟中断发生时(也就是每个时间片之间的间隔),或应用程序调用sched_yield()、sleep()等函数时,来决定要不要进行任务切换。在任务切换时,程序会将当前运行环境(包括rax,rbx,rbs,rsp等关键寄存器)压入当前任务的堆栈,再去下一个任务的堆栈中弹出这些运行环境相关的寄存器,跳转到上次中断的地方开始执行。在GPU中有这些机制吗?
答案是肯定的。CUDA就提供了线程切换的功能。CUDA的线程切换分为软件切换和硬件切换。所谓软件切换,就是利用load/store系列指令,将运行时上下文(指令指针寄存器和一些关键寄存器)保存到内存或从内存读取到寄存器,将用户的任务中断暂存起来,再切换到下一个任务。
为了打断正在执行的任务,在CUDA中,可以使用直接调用trap汇编指令,或利用assert来实现。
通过这些手段的组合,就可以中断一个用户的GPU运算任务执行,并保存现场上下文供切换回去。
首个实现了上下文切换的GPU虚拟化方案是在腾讯云上落地的,它叫做qGPU。q在这里是QoS的意思。使用了腾讯云TKE的用户可以利用qGPU来实现精细化颗粒度的GPU调度。
qGPU的出现,像工厂动力从蒸汽机时代跃进到电气化时代那样,是具有划时代的意义的。只有在实现了精细化的QoS以后,GPU虚拟化才可以用在运营级级别和企业生产级别的分布式系统中。
本期的话题涉及到了GPU内部的指令。在下一阶段的专题中,我们要介绍一些更有意思的GPU内部的实现——
请看下期。