2013-10-15 48 views
2

我有一個多線程CPU,我希望CPU的每個線程能夠啓動一個單獨的CUDA流。單獨的CPU線程將在不同的時間做不同的事情,所以有可能它們不會重疊,但如果它們同時啓動CUDA內核,我希望它能夠繼續同時運行。在每個主機線程上創建一個cuda流(多線程CPU)

我很確定這是可能的,因爲在CUDA工具包文檔部分3.2.5.5。它說:「甲流命令(可能由不同的主機線程發佈)的序列......」

所以,如果我想實現這一點,我會做類似

void main(int CPU_ThreadID) { 
    cudaStream_t *stream; 
    cudaStreamCreate(&stream); 

    int *d_a; 
    int *a; 
    cudaMalloc((void**)&d_a, 100*sizeof(int)); 
    cudaMallocHost((void**)&a, 100*8*sizeof(int)); 
    cudaMemcpyAsync(d_a, a[100*CPU_ThreadID], 100*size(int), cudaMemcpyHostToDevice, stream); 
    sum<<<100,32,0,stream>>>(d_a); 

    cudaStreamDestroy(stream); 
} 

這只是一個簡單的例。如果我知道只有8個CPU線程,那麼我知道至多8個流將被創建。這是做這件事的正確方法嗎?如果兩個或更多不同的主機線程在同一時間到達此代碼,這是否會同時運行?謝謝你的幫助!

編輯:

我糾正一些語法問題中的代碼塊,並放在cudaMemcpyAsync作爲sgar91建議。

+1

您不必'malloc''stream'指針。另外,如果你想讓流重疊,你可以考慮使用'cudaMemcpyAsync'。 – sgarizvi

+0

@ sgar91:流將處於不同的上下文中,因此它們將永遠不會重疊。 – talonmies

+0

@ sgar91謝謝!我已經在上面進行了這些修改。對於talonmies:那麼沒有辦法讓單獨的CPU線程同時訪問GPU設備嗎?如何強制線程使用與Robert Crovella建議的相同的上下文? – Miggy

回答

2

它真的讓我看起來像你提出了一個多進程應用程序,而不是多線程。你沒有提到你想到的是哪種線程架構,甚至是操作系統,但是我所知道的線程體系結構並沒有設置一個名爲「main」的線程例程,並且你沒有向線程代碼展示任何序言。

多進程環境通常會爲每個進程創建一個設備上下文,這會抑制細粒度的併發。即使這只是一個疏忽,我也會指出一個多線程應用程序應該在產生線程之前在所需的設備上建立一個GPU上下文。

然後每個線程都可以發出cudaSetDevice(0);或類似的調用,這應該會導致每個線程在指定的設備上獲取建立的上下文。

一旦到位,您應該能夠從您喜歡的任何線程向所需的流發出命令。

您可能希望參考cudaOpenMP示例代碼。雖然它省略了流概念,但它演示了一個多線程應用程序,可以讓多個線程向同一設備發出命令(並且可以擴展到相同的流)

內核是否碰巧併發運行或不是在上述問題已經解決後是一個單獨的問題。併發內核執行的數量爲requirements,並且內核本身必須具有兼容的資源需求(塊,共享內存,寄存器等),這通常意味着「小」內核。

+0

謝謝你的回答。我很確定它是多線程的,因爲構建應用程序的程序員說它是。我不知道,因爲我沒有建立它。不過,它是一種圖像處理算法,我知道在我們的8核CPU(超線程至16個線程)上,它一次處理15個圖像(一個線程仍然用於管理作業)。我使用窗戶。名字main就是我所說的訪問內核的.cu文件中的函數。它可以被稱爲任何東西。我會嘗試你的建議和例子,然後回來。再次感謝。對不起,我的困惑。 – Miggy

+0

對不起,我花了這麼長時間接受。我不得不擱置這個項目。我做了你所說的使用cudaOpenMP示例代碼作爲例子。我創建了一個C#程序,它使用System.Threading創建不同的CPU線程,每個線程都通過我的Cuda dll啓動一個內核。我使用NVIDIA Visual Profilier進行測試,並可以驗證它們是否在同一個Cuda上下文中以不同的流方式運行。我需要使用的主程序不是通過System.Threading創建線程,而是使用其他方法,所以我不確定如果這解決了我的問題,但是您將我設置在正確的軌道上。謝謝! – Miggy

相關問題