[英]CUDA streams not running in parallel
給出以下代碼:
void foo(cv::gpu::GpuMat const &src, cv::gpu::GpuMat *dst[], cv::Size const dst_size[], size_t numImages)
{
cudaStream_t streams[numImages];
for (size_t image = 0; image < numImages; ++image)
{
cudaStreamCreateWithFlags(&streams[image], cudaStreamNonBlocking);
dim3 Threads(32, 16);
dim3 Blocks((dst_size[image].width + Threads.x - 1)/Threads.x,
(dst_size[image].height + Threads.y - 1)/Threads.y);
myKernel<<<Blocks, Threads, 0, streams[image]>>>(src, dst[image], dst_size[image]);
}
for (size_t image = 0; image < numImages; ++image)
{
cudaStreamSynchronize(streams[image]);
cudaStreamDestroy(streams[image]);
}
}
查看nvvp
的輸出,即使第一個流是一個漫長的過程,其他流也應該能夠與之重疊,但是我幾乎可以完美地執行串行執行。
請注意,我的內核使用30個寄存器,並且所有內核都報告“已實現占用率”約為0.87。 對於最小的圖像,網格大小為[10,15,1],塊大小為[32,16,1]。
CUDA編程指南( 鏈接 )中給出了描述並發內核執行限制的條件,但要點是,只有在GPU有足夠資源來運行GPU的情況下,GPU才可能運行來自不同流的多個內核。
在您的用例中,您曾說過正在運行一個內核的多個啟動,每個內核有150個512個線程的塊。 您的GPU有12個SMM(我認為),並且每個SMM 最多可以同時運行4個塊(4 * 512 = 2048個線程,這是SMM的限制)。 因此您的GPU最多只能同時運行4 * 12 = 48個塊。 當在命令管道中多次啟動包含150個塊的啟動時,似乎幾乎沒有(也許甚至沒有)並發執行內核的機會。
如果通過減小塊大小來增加內核的調度粒度,則可能能夠鼓勵內核執行重疊。 與較大的塊相比,較小的塊更有可能找到可用資源和調度時隙。 同樣,減少每次內核啟動的總塊數(可能通過增加每個線程的並行工作量) 也可能有助於增加多個內核重疊或並行執行的可能性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.