GPU使用mps
参考文档: https://blog.csdn.net/weixin_41997940/article/details/124241226
什么是mps
mps简介
mps(Multi-Process Service),多进程服务。一组可替换的,二进制兼容的CUDA API实现,包括三部分: 守护进程 、服务进程 、用户运行时。
mps利用GPU上的Hyper-Q 能力:
- 允许多个CPU进程共享同一GPU context
- 允许不同进程的kernel和memcpy操作在同一GPU上并发执行,以实现最大化GPU利用率。
Hyper-Q介绍:
HyperQ 可以视为在设备端的硬件中实现的流: 在没有HyperQ时 ,来自所有流的命令(内核启动、内存传输等)由主机上的驱动程序放置在单个工作队列中。这意味着命令不能相互超越,必须careful issuing them in the right order on the host以达到最佳重叠。 在带有 HyperQ 的 GK110 GPU 和更高版本的设备上,设备上有(至少)32 个工作队列。来自不同队列的命令可以相对于彼此重新排序,直到它们开始执行。
支持的连接类型
- Multi cuda streams
- Multi cpu thrreads
- Multi cpu processes(MPS)
管理可并发的最大连接数:
- CUDA_DEVICE_MAX_CONNECTIONS = 32 (默认是8)
一般GPU上运行多个任务,都是采用"单任务"的工作模式,既同一个时刻只有一个任务( 用不同的context区分 )在GPU中运行。这种情况下,你同时启动了两个任务A和B,提交到GPU进行运行的时候是顺序进行的, 排队干活、分时复用 ,如下图所示:
什么是 CUDA context?
类似于CPU进程上下文,表示与特定进程关联的所有状态
- 从CPU端分配的GPU上的Global memory (cudaMalloc/cudaMallocManaged)
- Kernel函数中定义和分配的堆栈空间,例如local memory
- CUDA streams / events 对象
- 代码模块(*.cubin, *.ptx)
不同的进程有自己的CUDA context
每个context有自己的地址空间,并且不能访问其他CUDA context的地址空间
使用了mps之后,共用了context,同一时刻两个任务可以一起跑。这样更加充分的利用了GPU的算力。
mps带来的好处
- 提升GPU利用率(时间上)和占用率 (空间上)
- 减少GPU上下文切换时间
- 减少GPU上下文存储空间
如何使用mps
单卡使用mps
设置独占 :
sudo nvidia-smi -i 0 -c EXCLUSIVE_PROCESS
启动mps守护进程:
export CUDA_VISIBLE_DEVICES=0
nvidia-cuda-mps-control -d
查看守护进程:
ps -ef | grep mps
关闭:
echo quit | nvidia-cuda-mps-control
sudo nvidia-smi -i 0 -c 0
配置mps的脚本:
设置资源占用量修改OpenMPS 100即可,0-100之间。50即为半卡,25四分之一卡。
#!/bin/bash
echo "please ensure 'nvidia-smi -i 0 -c EXCLUSIVE_PROCESS' "
echo "press any key to continue"
read
OpenMPS(){
nvidia-cuda-mps-control -d
echo "[MPS]: set mps default_active_thread_percentage: $1"
echo set_default_active_thread_percentage $1|nvidia-cuda-mps-control
}
CloseMPS(){
echo "[MPS]: close mps control daemon"
echo quit | nvidia-cuda-mps-control
}
CloseMPS
OpenMPS 100
多卡使用mps
只需要修改卡的参数即可:(0为0号卡,1为1号卡)
nvidia-smi -i 0,1 -c EXCLUSIVE_PROCESS
export CUDA_VISIBLE_DEVICES=0,1
使用nvprof抓取log
nvprof --profile-all-processes --csv --log-file output_%p.csv