2012-02-16 159 views
6

對CUDA內核使用不同的流可以使併發內核執行成爲可能。因此,n內核上的n流理論上可以併發運行,如果它們適合硬件,對吧?CUDA並行內核執行,每個流有多個內核

現在我面臨以下問題:沒有n不同的內核,但n*m其中m內核需要按順序執行。例如n=2m=3會導致下面的執行方案與流:

Stream 1: <<<Kernel 0.1>>> <<<Kernel 1.1>>> <<<Kernel 2.1>>> 
Stream 2: <<<Kernel 0.2>>> <<<Kernel 1.2>>> <<<Kernel 2.2>>> 

我天真的假設是,內核X.0和Y.1至少應該同時執行(從一個理論點)或不是連續的(從實際的角度來看)。但是我的測量結果告訴我,情況並非如此,似乎是執行了連續執行(即K0.0,K1.0,K2.0,K0.1,K1.1,K2.1)。內核本身非常小,所以併發執行不應該成爲問題。

現在我的方法是完成一種調度,以確保內核以交錯方式進入GPU上的調度器。但是當處理大量的流/內核時,這可能會造成更多的傷害而不是好處。

好吧,直接點:什麼是適當的(或至少不同)的方法來解決這種情況?

編輯:測量通過使用CUDA事件完成。我測量了完全解決計算所需的時間,即GPU必須計算所有的n * m內核。假設是:在完全併發的內核執行上,執行時間大致(理想情況下)是按順序執行所有內核所需的時間的1/n倍,因此必須有兩個或多個內核可以同時執行的時間。我現在只用兩種不同的流來確保這一點。

我可以測量使用所描述的流和調度內核交錯的執行時間之間的明顯差異, Ë:

Loop: i = 0 to m 
    EnqueueKernel(Kernel i.1, Stream 1) 
    EnqueueKernel(Kernel i.2, Stream 2) 

Loop: i = 1 to n 
    Loop: j = 0 to m 
     EnqueueKernel(Kernel j.i, Stream i) 

後者導致更長的運行時間。

編輯#2:更改流號碼開頭1(而不是0,請參閱下面的註釋)。

編輯#3:硬件是NVIDIA的Tesla M2090(即費米,計算能力2.0)

+0

您可能需要使用某些流同步基元來執行您所需的執行順序。但是,您是否可以擴展一些關於如何在您的問題中進行測量的問題,並且您是否還可以確認,在編寫「數據流0」時,您不一定是指CUDA數據流0? – talonmies 2012-02-16 12:42:03

+0

我澄清了測量(至少我希望如此)。對於流,我意指'cudaStream_t'的實例,如[CUDA C編程指南](http://developer.download.nvidia.com/compute/DevZone/docs/html/C/doc/CUDA_C_Programming_Guide.pdf)中所述。第3.2.5節(異步併發執行)。 – 2012-02-16 12:57:13

+2

也許你誤解了我的要求 - 我的意思是你的一個流CUDA流0,因爲流0(默認流)是同步的。 – talonmies 2012-02-16 13:09:28

回答

5

在費米(又名計算能力2.0),硬件最好是交錯的內核啓動到多個數據流,而不是將所有內核啓動到一個流,然後是下一個流等。這是因爲如果有足夠的資源,硬件可以立即將內核啓動到不同的流,而如果後續啓動到同一個流,則通常會引入延遲,從而降低併發性。這就是你的第一種方法表現更好的原因,這種方法是你應該選擇的方法。

啓用性能分析還可以禁用費米的併發性,所以要小心。另外,請注意在啓動循環期間使用CUDA事件,因爲這些干擾可能會干擾 - 例如,最好使用事件的整個循環來計時。

+0

你能否給我一個知識源(第一段而不是第二段)來自哪裏? – 2012-02-21 13:37:43

+0

CUDA 4.1編程指南的第3部分有信息。然而,在閱讀它之後,我發現它沒有明確地說「交織內核啓動」。我從NVIDIA CUDA軟件團隊的同事處獲得了相關信息。 – harrism 2012-02-22 00:59:09

+0

感謝您的更新。如果可能,我將重新訪問我的代碼並提供更多信息/更新。 – 2012-02-22 07:55:16