GPU并行效率问题——通过MPS提升GPU计算收益

news/2024/9/23 10:19:32/

现象描述

使用V100_32G型号的GPU运行计算程序时,发现程序每5秒能够完成一次任务,耗费显存6G。

鉴于V100 GPU拥有32G的显存,还有很多空闲,决定同时运行多个计算程序,来提升GPU计算收益。

然而,这一切都是想当然的。运行多个计算程序时,每个计算程序的处理耗时大大增加。例如,同时运行4个计算程序,则这些计算程序差不多需要20秒才能完成一次任务,几乎是单进程运行时的4倍,算上并行的收益,20秒能够处理4个任务,这和单进程的计算程序的运行效果几乎没有区别,也就是说,多进程并行和单进程运行完全没有效率的提升。

单进程:

5秒/任务

4进程:

20秒/任务

问题原因

一种可能的解释是,当前的计算程序对GPU的利用率很高,单进程执行时已经几乎占用全部的GPU计算核心,因此,多进程执行实际上也只相当于单进程执行,但事实并非如此。

与单核CPU的调度方式类似,在单一时间片内,GPU中只会有一个GPU进程在运行,当多个进程同时把CUDA任务发射到GPU时,GPU使用时间片轮转调度的方式,多个GPU进程之间在微观层面上是交替运行的。这也导致,在某一个时间片内,如果正在运行的GPU进程没有很好地利用计算资源,那么空闲的计算资源就是浪费掉的。也就是说,GPU并没有真正地进行并发计算。再加上不同进程的上下文切换,也带来了更多的时间开销。

MPS简介

Nvidia针对多进程并发执行的场景推出了多进程服务解决方案-MPS,该方案可以做到空分复用。

MPS的运行模式为一个MPS Server和多个MPS Client。MPS Server通过一个CUDA Context管理GPU硬件资源,每个MPS Client对应一个GPU进程,多个MPS Client会将它们的任务通过MPS Server传入GPU,MPS Server可以把多个进程的上下文进行融合,合并后的进程将多个进程的Kernel交织到一起进行发射,从而越过了硬件时间分片调度的限制,使得它们的CUDAkernels实现真正意义上的并行,这可以带来以下好处:

> 进程之间无需上下文切换,减少了上下文切换的开销。

> 同一个时间片里,多个进程的kernel一起执行,提升了GPU计算资源的利用率。

MPS在单进程对GPU利用率不高的情况下是非常有用的,MPS的缺点则在于故障隔离问题,本文忽略。

MPS的使用

1. 启动MPS。

a. 设置GPU计算模式为exclusive mode。

设置GPU compute mode 为 exclusive mode (非必须,但推荐设置,设置后有可能使得原本正常的计算程序运行失败)

nvidia-smi -i 0 -c EXCLUSIVE_PROCESS

注意:

执行该设置需要root权限。

除非使用-i参数指定单个GPU,否则将影响所有GPU。

此操作的效果立即生效,但它不会在主机重新启动后持续存在,主机重新启动后,计算模式将重置为“DEFAULT”。

补充说明:

-c选项设置目标GPU的计算模式。计算模式标志指示单个或多个计算应用程序是否可以在GPU上运行。

0/Default:表示每个设备允许多个上下文。

1/Exclusive_Thread:已弃用,改用 Exclusive_Process。

2/Prohibited:表示每台设备不允许使用任何上下文(无计算应用程序)。

3/Exclusive_Process:表示每个设备只允许一个上下文,一次可从多个线程使用。

b. 启动MPS守护进程。

服务器中有多个GPU时,选择特定的GPU运行程序可在程序运行命令前使用:CUDA_VISIBLE_DEVICES=0命令。0为服务器中的GPU编号,可以为0, 1, 2, 3等,表明对程序可见的GPU编号。

CUDA_VISIBLE_DEVICES=1

只有编号为1的GPU对程序是可见的,在代码中gpu[0]指的就是这块GPU

CUDA_VISIBLE_DEVICES=0,2,3

只有编号为0,2,3的GPU对程序是可见的,在代码中gpu[0]指的是第0块,gpu[1]指的是第2块,gpu[2]指的是第3块

CUDA_VISIBLE_DEVICES=2,0,3

只有编号为0,2,3的GPU对程序是可见的,但是在代码中gpu[0]指的是第2块,gpu[1]指的是第0块,gpu[2]指的是第3块

首先设置CUDA变量:

export CUDA_VISIBLE_DEVICES=0

export CUDA_MPS_PIPE_DIRECTORY=/tmp/nvidia-mps

(cuda 7.0以后非必须)

export CUDA_MPS_LOG_DIRECTORY=/tmp/nvidia-log

(cuda 7.0以后非必须)

启动mps:

nvidia-cuda-mps-control -d

查看MPS 守护进程是否正在运行:

ps -ef | grep mps

此时可以看到一个mps进程:

root 1826 1 0 Nov27 ? 00:00:04 nvidia-cuda-mps-control -d

接着运行计算程序,并再次查看mps进程,此时可以看到多出了一个mps-server进程:

root 1826 1 0 Nov27 ? 00:00:04 nvidia-cuda-mps-control -d

root 2544 1826 0 Nov27 ? 00:00:43 nvidia-cuda-mps-server

2. 关闭MPS。

关闭mps-control:

echo quit | nvidia-cuda-mps-control

让GPU计算模式恢复为默认模式:

nvidia-smi -i 0 -c DEFAULT

3. Volta MPS资源配置。

nvidia-cuda-mps-control

set_default_active_thread_percentage 10

该命令为每个MPS Client限制10%的threads。不是为每个Client预留专用资源,而是限制它们可以最多使用多少threads。默认情况下,每个Client可以获取所有threads(即100%)。

4. MPS与docker。

为了配合MPS的使用,docker在创建容器时需要通过

--ipc=host

参数启用内存共享:

docker run -itd --gpus all --ipc=host --network host -p 5501:5501 -v /mnt/data/enhancefox:/home/server-v /etc/timezone:/etc/timezone -v /etc/localtime:/etc/localtime --name enhancefox vsr_trt

注意:

在没有启动MPS的情况下,这样创建的容器仍然能够正常运行(非MPS模式);此时,在启动mps之后,即使重启docker中的程序,该程序仍然不会以mps模式运行。要以mps模式运行程序,必须重启docker:

docker restart enhancefox

5. 如何查看GPU进程是否处于MPS模式?

通过NVIDIA的nvidia-smi命令我们可以知道显卡上的任务可以分为图形图像任务和计算任务两种,其中图形图形任务类型为Graphic,计算任务类型(Type)为compute,缩写分别为G和C,在使用nvidia-smi命令后我们可以通过查看process内容知道不同的进程是属于G类型还是C类型。当启用MPS之后,Type将会对应地变为M+G或者M+C:


http://www.ppmy.cn/news/307006.html

相关文章

GPU计算(一)

简单描述 图形处理、也就是显示核心,又称显示核心、视觉处理器、显示芯片,是一种专门在个人电脑、工作站、游戏机和一些移动设备(如平板电脑、智能手机等)上图像运算工作的微处理器。 包括市面上的游戏本也是带有独立显卡的&…

MXNet使用GPU计算

GPU上的存储 在MXNet中,mx.cpu()代表所有的物理CPU和内存,而mx.gpu()只代表一块GPU和相应的显存。(cpu对应内存,gpu对应显存) 可以通过NDArray的context属性来查看该NDArray所在的设备。 x.context 我们可以通过多种方法创建NDArray到GPU…

python调用显卡计算_Anaconda GPU计算入门指南

摘要:随着人工智能时代的到来,计算能力变得越来越重要。GPU计算已经成为了必然的趋势,对于机器学习爱好者来说要想训练一个高质量的神经网络,使用GPU无疑是最佳选择。 GPU计算已成为数据科学领域的重要组成部分。计算需求的不断增长,使得GPU计算逐渐流行起来。此外,现在每…

GPU计算

文章目录 GPU计算1. GPU和CPU的区别2. GPU的主要参数解读3. 如何在pytorch中使用GPU4. 市面上主流GPU的选择 GPU计算 1. GPU和CPU的区别 设计目标不同,CPU基于低延时,GPU基于高吞吐。 CPU:处理各种不同的数据类型,同时又要逻辑…

浅析GPU计算——CPU和GPU的选择

目前市面上介绍GPU编程的博文很多,其中很多都是照章宣科,让人只能感受到冷冷的技术,而缺乏知识的温度。所以我希望能写出一篇可以体现技术脉络感的文章,让读者可以比较容易理解该技术,并可以感悟到cuda编程设计及优化的…

Matlab 并行计算学习初步

Matlab 并行计算学习 1. 简介 高性能计算(High Performance Computing,HPC)是计算机科学的一个分支,研究并行算法和开发相关软件,致力于开发高性能计算机。可见并行计算是高性能计算的不可或缺的重要组成部分。 1.1 并行计算 并行计算&am…

什么是GPU计算

什么是GPU计算 Nvidia公式发布了了CUDA,它是建立在NVIDA的CPUs上的一个通用并行计算平台和编程模型,基于CUDA编程可以利用GUPs的并行计算引擎来更加高效地解决比较复杂的计算难题GPU并不是一个独立运行的计算平台,而需要与CPU协同工作&#…

Apache Hudi初探(九)(与spark的结合)--非bulk_insert模式

背景 之前讨论的都是’hoodie.datasource.write.operation’:bulk_insert’的前提下,在这种模式下,是没有json文件的已形成如下的文件: /dt1/.hoodie_partition_metadata /dt1/2ffe3579-6ddb-4c5f-bf03-5c1b5dfce0a0-0_0-41263-0_202305282…