現(xiàn)象描述
使用V100_32G型號的GPU運行計算程序時,發(fā)現(xiàn)程序每5秒能夠完成一次任務(wù),耗費顯存6G。
鑒于V100 GPU擁有32G的顯存,還有很多空閑,決定同時運行多個計算程序,來提升GPU計算收益。
然而,這一切都是想當(dāng)然的。運行多個計算程序時,每個計算程序的處理耗時大大增加。例如,同時運行4個計算程序,則這些計算程序差不多需要20秒才能完成一次任務(wù),幾乎是單進程運行時的4倍,算上并行的收益,20秒能夠處理4個任務(wù),這和單進程的計算程序的運行效果幾乎沒有區(qū)別,也就是說,多進程并行和單進程運行完全沒有效率的提升。
單進程:
5秒/任務(wù)
4進程:
20秒/任務(wù)
問題原因
一種可能的解釋是,當(dāng)前的計算程序?qū)PU的利用率很高,單進程執(zhí)行時已經(jīng)幾乎占用全部的GPU計算核心,因此,多進程執(zhí)行實際上也只相當(dāng)于單進程執(zhí)行,但事實并非如此。
與單核CPU的調(diào)度方式類似,在單一時間片內(nèi),GPU中只會有一個GPU進程在運行,當(dāng)多個進程同時把CUDA任務(wù)發(fā)射到GPU時,GPU使用時間片輪轉(zhuǎn)調(diào)度的方式,多個GPU進程之間在微觀層面上是交替運行的。這也導(dǎo)致,在某一個時間片內(nèi),如果正在運行的GPU進程沒有很好地利用計算資源,那么空閑的計算資源就是浪費掉的。也就是說,GPU并沒有真正地進行并發(fā)計算。再加上不同進程的上下文切換,也帶來了更多的時間開銷。
MPS簡介
Nvidia針對多進程并發(fā)執(zhí)行的場景推出了多進程服務(wù)解決方案-MPS,該方案可以做到空分復(fù)用。
MPS的運行模式為一個MPS Server和多個MPS Client。MPS Server通過一個CUDA Context管理GPU硬件資源,每個MPS Client對應(yīng)一個GPU進程,多個MPS Client會將它們的任務(wù)通過MPS Server傳入GPU,MPS Server可以把多個進程的上下文進行融合,合并后的進程將多個進程的Kernel交織到一起進行發(fā)射,從而越過了硬件時間分片調(diào)度的限制,使得它們的CUDAkernels實現(xiàn)真正意義上的并行,這可以帶來以下好處:
> 進程之間無需上下文切換,減少了上下文切換的開銷。
> 同一個時間片里,多個進程的kernel一起執(zhí)行,提升了GPU計算資源的利用率。
MPS在單進程對GPU利用率不高的情況下是非常有用的,MPS的缺點則在于故障隔離問題,本文忽略。
MPS的使用
1. 啟動MPS。
a. 設(shè)置GPU計算模式為exclusive mode。
設(shè)置GPU compute mode 為 exclusive mode (非必須,但推薦設(shè)置,設(shè)置后有可能使得原本正常的計算程序運行失敗)
nvidia-smi -i 0 -c EXCLUSIVE_PROCESS
注意:
執(zhí)行該設(shè)置需要root權(quán)限。
除非使用-i參數(shù)指定單個GPU,否則將影響所有GPU。
此操作的效果立即生效,但它不會在主機重新啟動后持續(xù)存在,主機重新啟動后,計算模式將重置為“DEFAULT”。
補充說明:
-c選項設(shè)置目標GPU的計算模式。計算模式標志指示單個或多個計算應(yīng)用程序是否可以在GPU上運行。
0/Default:表示每個設(shè)備允許多個上下文。
1/Exclusive_Thread:已棄用,改用 Exclusive_Process。
2/Prohibited:表示每臺設(shè)備不允許使用任何上下文(無計算應(yīng)用程序)。
3/Exclusive_Process:表示每個設(shè)備只允許一個上下文,一次可從多個線程使用。
b. 啟動MPS守護進程。
服務(wù)器中有多個GPU時,選擇特定的GPU運行程序可在程序運行命令前使用:CUDA_VISIBLE_DEVICES=0命令。0為服務(wù)器中的GPU編號,可以為0, 1, 2, 3等,表明對程序可見的GPU編號。
CUDA_VISIBLE_DEVICES=1 |
只有編號為1的GPU對程序是可見的,在代碼中g(shù)pu[0]指的就是這塊GPU |
CUDA_VISIBLE_DEVICES=0,2,3 |
只有編號為0,2,3的GPU對程序是可見的,在代碼中g(shù)pu[0]指的是第0塊,gpu[1]指的是第2塊,gpu[2]指的是第3塊 |
CUDA_VISIBLE_DEVICES=2,0,3 |
只有編號為0,2,3的GPU對程序是可見的,但是在代碼中g(shù)pu[0]指的是第2塊,gpu[1]指的是第0塊,gpu[2]指的是第3塊 |
首先設(shè)置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. 關(guān)閉MPS。
關(guān)閉mps-control:
echo quit | nvidia-cuda-mps-control
讓GPU計算模式恢復(fù)為默認模式:
nvidia-smi -i 0 -c DEFAULT
3. Volta MPS資源配置。
nvidia-cuda-mps-control
set_default_active_thread_percentage 10
該命令為每個MPS Client限制10%的threads。不是為每個Client預(yù)留專用資源,而是限制它們可以最多使用多少threads。默認情況下,每個Client可以獲取所有threads(即100%)。
4. MPS與docker。
為了配合MPS的使用,docker在創(chuàng)建容器時需要通過
--ipc=host
參數(shù)啟用內(nèi)存共享:
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的情況下,這樣創(chuàng)建的容器仍然能夠正常運行(非MPS模式);此時,在啟動mps之后,即使重啟docker中的程序,該程序仍然不會以mps模式運行。要以mps模式運行程序,必須重啟docker:
docker restart enhancefox
5. 如何查看GPU進程是否處于MPS模式?
通過NVIDIA的nvidia-smi命令我們可以知道顯卡上的任務(wù)可以分為圖形圖像任務(wù)和計算任務(wù)兩種,其中圖形圖形任務(wù)類型為Graphic,計算任務(wù)類型(Type)為compute,縮寫分別為G和C,在使用nvidia-smi命令后我們可以通過查看process內(nèi)容知道不同的進程是屬于G類型還是C類型。當(dāng)啟用MPS之后,Type將會對應(yīng)地變?yōu)镸+G或者M+C:文章來源:http://www.zghlxwxcb.cn/news/detail-559688.html

文章來源地址http://www.zghlxwxcb.cn/news/detail-559688.html
到了這里,關(guān)于GPU并行效率問題——通過MPS提升GPU計算收益的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!