簡體   English   中英

CUDA流未並行運行

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM