GUP虚拟化
目前,有多种软件技术方案可以实现GPU虚拟化,通常可分为内核态虚拟化和用户态虚拟化两大类。本文将主要讨论这两类方案的区别,为后续分享GPU远程调用做准备。
以英伟达的GPU为例,应用到硬件从上至下分为用户态、内核态、GPU硬件三个层次。
用户态层:用户态是应用程序使用CUDA API来编写并行计算任务,并通过调用CUDA API与GPU用户态驱动进行通信。
内核态层:主要运行的是GPU的内核态驱动程序,它与操作系统内核紧密集成,受到操作系统以及CPU硬件的特殊保护。
硬件层:这个就是硬件虚拟化,类似于 Nvidia MIG.
用户态
用户态虚拟化:利用CUDA、OpenGL等标准接口,对API进行拦截和转发,对被拦截的函数进行解析,然后调用硬件厂商提供的用户态库中的相应函数(见下图)。
经过API拦截之后,用户态虚拟化方案还可以利用RPC的方式进行远程API Remoting,即CPU主机可以通过网络调用GPU主机的GPU,实现GPU的远程调用。
这个技术方案拥有几个优点:
1、CUDA、OpenGL等接口都是公开的标准化接口,具有开放性和接口稳定性。
2、因为该方案运行在用户态,可以规避内核态代码过于复杂容易引入安全问题。
3、由于该方案工作在用户态,从部署形态上对用户环境的侵入性最小,也最安全。
4、可以支持统一内存接口,然后就可以借用主机内存。
这个方案也有缺点:
1. 相比于内核态接口,用户态API接口的数量比内核态接口的数量要高几个数量级。
内核态
内核态虚拟化:第三方厂商所做的内核态虚拟化方案通过拦截ioctl、mmap、read、write等这类内核态与用户态之间的接口来实现GPU虚拟化。
这个技术方案的优点是:
1、有较好的灵活性,不依赖GPU硬件,可以在数据中心级和消费级的GPU上使用。
2、在GPU共享的同时,具备不错的隔离能力。
3、由于只支持运行在容器环境中,研发工作量相比用户态方案要小得多。
这个方案也有缺点:
1、需要在内核态层插入文件,对系统的侵入性大,容易引入安全隐患;并且私有云环境客户内核版本各不一样,也会增加安全风险。
2、第三方厂商需要通过一定程度的逆向工程来分析这些接口的实现。这种行为存在着极大的法律风险和不确定性,可持续性远低于用户态方案。
3、目前只能支持在容器环境下使用。
4、不能支持使用统一内存。
跨进程空间
上述两种虚拟化方案在经过接口拦截之后又分为两种:
同一个进程空间的接口解析和不同进程空间的接口解析
同一个进程空间的接口解析:用户态容器虚拟化和内核虚拟化技术路线也有一个非常明显的限制,就是只能在同一个进程空间内进行接口的拦截、解析和执行。因此这种技术路线从原理上就无法支持跨OS内核的KVM虚拟化,更无法跨越物理节点做到远程调用GPU。
不同进程空间的接口解析:由于应用程序和GPU管理软件栈(例如GPU驱动)已经不在一个操作系统的管理下,因此资源就不再是共享的了,视图也不再是统一的了。以英伟达的 CUDA 为例有数万个接口,需要对每一个接口都进行跨进程空间的接口解析,然后进行行为模拟。
GPU虚拟化和资源池化不同的技术方案和实现有不同的特点。