2014-01-27 77 views
0

我有一個處理大量數據的CUDA內核。 因爲我不能一次傳輸所有數據,所以我不得不將它們分成塊,並按塊處理它們並更新GPU上的輸出。 我正在解析文件中的輸入數據。 我在想如果我可以通過在主機和GPU中有兩個緩衝區來重疊塊的內存傳輸。在處理一個卡盤時,我可以讀取另一個卡片,將其轉移到GPU並將內核啓動到同一個流。 我的問題是內核的執行時間比分析數據並將它們傳送到GPU要慢。我如何確保memcpys不會覆蓋內核使用的數據,因爲memcpys沒有被阻塞?cuda內存計算重疊問題

//e.g. Pseudocode 
//for every chunk 
    //parse data 
    //cudaMemcpyAsync (dev, host, size, H2D) 
    //launch kernel 
    //switch_buffer 
//copy result from device to host 

在此先感謝您。

+1

如果這是一個選項,不要每次重複使用相同的內存並切換緩衝區,可以看看這個[webinar](http://on-demand.gputechconf.com/gtc-快遞/ 2011 /簡報/ StreamsAndConcurrencyWebinar.pdf)。一種可能性是爲每對相關的memcpy和內核啓動使用不同的流。你也必須確保你使用固定內存!在您的僞代碼中,'cudaMemcpyAsync'中也缺少用過的cuda流。 – hubs

回答

0

只需在內核啓動後插入帶cudaDeviceSynchronize()的顯式同步點。

這樣,你基本上開始了內存傳輸並同時啓動了一個內核。轉移將轉到一個緩衝區,內核將在另一個緩衝區中工作。 cudaDeviceSynchronize()會一直等到兩個都完成,屆時您將交換緩衝區並重復。當然,你還需要將結果從設備複製到循環中的主機,並添加邏輯來處理第一次迭代,當沒有數據供內核處理時,以及最後一次迭代,當出現沒有更多的數據要複製,但仍然需要處理一個緩衝區。這可以通過循環內的邏輯來完成,或者通過部分展開循環來專門編碼第一次和最後一次迭代。

編輯:

通過剛纔的cudaMemcpyAsync()前後文件後,讀取並解析移動同步點,你允許內核也有重疊的處理的那部分(如果內核運行足夠長) 。

+0

我有這個與cudaDeviceSynchronize實現,但我想避免它,因爲它需要時間。不過,我看不到任何其他方式來確保我想要的。謝謝。 – user2117698

+0

@ user2117698,如果你像Roger描述的那樣使用雙緩衝區,那麼它不會花費額外的時間。您的潛在加速受限於您的工作負載在傳輸和計算之間平均分配的程度。如果這兩個緩衝區足夠大,那麼啓動內核啓動和memcpy的開銷將被隱藏,並且性能將以其自然的傳輸/處理有界性的程度結束。 – ArchaeaSoftware