《Learning CUDA Programming》讀書筆記(四)

Kernel執行,GPU和Host之間數據Copy,都是有CUDA Stream管理的;

default stream默認不能與其他stream並行執行;即其他stream都結束後,default stream才能開始執行,他結束後,其他stream才能開始執行;(其他stream用cudaStreamCreateWithPriority可以設爲和default stream能並行!)

實現Pipeline並行的條件:

1. Host上開闢的是pinned memory;

2. 使用非阻塞的cudaMemcpyAsync;

3. 使用多個Stream

一塊卡上能不能同時並行跑來自多個Stream的多個Kernel,取決於GPU核的佔用情況(當前Kernel佔滿了所有核,則不會調度下一個Kernel同時執行;

cudaStreamAddCallback可以讓Stream上的某些任務完成後,調用該CPU端函數,該函數結束後,該Stream再執行後續任務;

cudaStreamCreateWithPriority可以創建帶優先級的Stream, 並且指定該Stream是否要與default stream是同步的關係(如果指定爲異步關係即cudaStreamNonBlocking,則該Stream和default stream可以並行執行)

高優先級的Stream的Kernel, 居然可以搶佔低優先級Stream的;profiler圖上會顯示低優先級Stream的Kernel執行時間變長,其實期間是被搶佔了沒有真正執行;

用cudaEvent_t來卡時間的好處:1. 可以不用去讓host和device同步;2. 更精確;3.可以爲多個Stream卡時間;

dynamic parallelism: 在Kernel裏再啓動子Kernel;可以實現遞歸調用,但是層數有限制的;

Grid-level Coorperative Group,可以讓之前“Kernel結束再起一個Kernel做Reduce”的開銷避免,不用新啓Kernel就能實現Grid級的同步;

限制就是啓動的block數目不能超過硬件和Kernel共同決定的max active block數目(可調API獲得這個數目)(這裏的active, 指的是SM寄存器和Shared-memory能承受的最大值,不是和core數一樣那個)

因爲block數目受限,所以性能也許反而下降,因爲hide memory訪問latency的能力下降了;

 

Multi-Process Service(MPS):

如果默認多進程使用同一個GPU,即使單個Kernel都佔不滿GPU,系統也會分時複用該GPU(即時間片輪轉調度,獨佔式);

使用了MPS,多個進程的多個Kernel可以同時在一個GPU上執行(除非一個Kernel佔滿整個GPU,否則可能會同時把一個Kernel佔不滿的GPU SM分配給另一個進程的Kernel);

要先啓動一個CUDA的daemon進程,然後就不用管了;(本質上是多個進程把Kernel提交給這個daemon進程,由該進程來往GPU上提交任務,所以NVProfiler裏看上去,也是同一個進程的多個Stream並行執行的)

多Kernel同時在一個GPU卡上跑的另一個好處是,能Hide其中某些Kernel的訪存Latency;

演示了NV Profiler怎麼展示多進程的profiling結果;(暫不支持異步MPI調用)

簡單的y[i]=a*x[i]+b任務,啓動1次Kernel內嵌循環迭代N次,速度10倍於,啓動N次Kernel(開銷在於啓動Kernel時間和讀顯存至寄存器的時間),速度10倍於,在Kernel裏遞歸啓動Kernel調N層(爲什麼這麼慢?)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章