MPS(Multi-Process Scheduling)
MPS多进程调度是CUDA应用程序编程接口的替代二进制兼容实现。从Kepler的GP10 架构开始,NVIDIA 引入了MPS ,允许多个流(Stream)或者CPU 的进程同时向GPU 发射Kernel 函数,结合为一个单一应用程序的上下文在GPU上运行,从而实现更好的GPU利用率。当使用MPS时,MPS Server会通过一个 CUDA Context 管理GPU硬件资源,多个MPS Clients会将他们的任务通过MPS Server 传入GPU ,从而越过了硬件时间分片调度的限制,使得他们的CUDA Kernels 实现真正意义上的并行。但MPS由于共享CUDA Context也带来一个致命缺陷,其故障隔离差,如果一个在执行kernel的任务退出,和该任务共享share IPC和UVM的任务一会一同出错退出。
System Considerations
Limitation:
-
MPS只能在Linux os;如果在其他os上,MPS server会无法成功启动。
-
不支持Tegra
-
要求Compute capacity>=3.5, 如果某个可见的GPUM< 3.5, MPS server启动会失败;
-
CUDA的UVA必须可用 (compute capability>=2.0, 在64bit的CUDA程序里是默认设置)
-
MPS clients可用的页锁定内存大小,由tmpfs 文件系统的大小限制 (/dev/shm)
-
对MPS server应用独占模式-Exclusive-mode restrictions, 不能对MPS client应用独占模式;
-
一个系统只有一个用户可用由一个active MPS server(?)
-
所有的MPS client行为可用被系统监控工具统计给MPS server进程
GPU Compute modes 三种计算模式
-
PROHIBITED - GPU 此时无法用于计算应用;
-
EXCLUSIVE_PROCESS - GPU一次只能分配给一个进程;单个进程的多个线程可以向GPU同时提交任务;
-
DEFAULT - 多个进程可用同时使用GPU, 单个进程的多个线程可以向GPU同时提交任务;
使用MPS , 对于所有MPS clients来说,可让EXCLUSIVE_PROCESS表现得像DEFAULT模式。
Nvidia推出了MPS方案,这是一种算力分割的软件虚拟化方案。该方案和PCIe SR-IOV方案相比,配置很灵活,并且和docker适配良好。
MPS基于C/S架构,配置成MPS模式的GPU上运行的所有进程,会动态的将其启动的内核发送给MPS server,MPS Server借助CUDA stream,实现多个内核同时启动执行。除此之外,MPS还可配置各个进程对GPU的使用占比。
但该方案的一个问题在于,各个服务进程依赖MPS,一旦MPS进程出现问题,所有在该GPU上的进程直接受影响,需要使用Nvidia-smi重置GPU 的方式才能恢复。
启动 mps-control
nvidia-cuda-mps-control -d # Start daemon in background process
ps -ef | grep mps # See if the MPS daemon is running.
单卡使用mps
设置独占 :
sudo nvidia-smi -i 0 -c EXCLUSIVE_PROCESS
启动mps守护进程:
export CUDA_VISIBLE_DEVICES=0
nvidia-cuda-mps-control -d
查看守护进程:
ps -ef | grep mps
多卡使用mps,只需要修改卡的参数即可:(0为0号卡,1为1号卡)
nvidia-smi -i 0,1 -c EXCLUSIVE_PROCESS
export CUDA_VISIBLE_DEVICES=0,1
命令 nvidia-smi -i 0,1 -c 3 同样使用了 NVIDIA 的系统管理接口(nvidia-smi)工具,但这里的 -c 参数后面跟的是数字 3,而不是之前提到的 EXCLUSIVE_PROCESS。在 NVIDIA 的文档中,计算模式(compute mode)可以通过指定不同的值来设置:
0 或 DEFAULT:默认模式,允许多个进程同时使用 GPU。
1 或 EXCLUSIVE_PROCESS:独占进程模式,每个 GPU 只能被一个进程独占使用。
2:禁止模式(这个值并不常见,并且可能不会在所有版本或类型的 GPU 上都有效)。
3:保留给未来的使用,当前的行为等同于默认模式。
-i 0,1 或 --gpu-id=0,1:这部分指定了要管理的 GPU 的 ID。在本例中,0 和 1 是 GPU 的索引,通常从 0 开始编号。这意味着命令将应用于系统中的第一个和第二个 GPU。
关闭mps-control
echo quit | nvidia-cuda-mps-control
nvidia-smi -i 0 -c DEFAULT
GPU虚拟化和共享有多种方案,英伟达从官方也提供了vGPU、MIG、MPS等方案,以及非官方的vCUDA、rCUDA、内核劫持等多种方案。