2014-10-11 84 views
0

我見過很多並行掃描的實現;兩個主要的希利斯&鋼和blelloch掃描。雖然我見過的所有實現都在共享內存中工作,但內存僅在塊中的線程之間共享。如何在每個塊的線程數多於每個線程的線程上執行並行掃描?

是否有任何掃描的實現可以在比每個塊的線程數多的數組上工作,即數組將不適合共享內存?

這個環節提到的掃描實現我在所有搜索看到,一個希利斯斯蒂爾版本,例如39-1 http://http.developer.nvidia.com/GPUGems3/gpugems3_ch39.html

是做在子陣列一分段掃描陣列內,然後做一個唯一的選擇「最終掃描」從前面的子陣列中添加一個幅度值到下一個?

回答

2

無論有沒有共享內存,CUDA內核都可以以任意順序執行的塊(線程塊)執行。要充分利用硬件,您的內核調用中必須有多個線程塊,但這會產生不確定的執行順序。

正因爲如此,掃描算法在大型數組上工作時,必然需要以線程塊大小的塊(以某種方式)工作。如果我們有多個線程塊,那麼給定的線程塊無法知道其他線程塊是否已完成相鄰數據的工作。 (是的,有設計的機制來允許線程間塊通信,但是這些都是困難的並且不能大規模地解決問題。)

這樣的算法通常意味着這樣的算法意味着全球同步的某種類型,唯一的安全在任何情況下的全球同步是內核啓動。線程塊可以獨立完成一部分工作,但是當需要將線程塊的工作拼接在一起時,我們必須等到步驟A在所有線程塊之間完成後再繼續步驟B.

因此,我認爲你會發現大多數設備範圍的掃描算法,包括您鏈接的第39章GPU Gems示例,以及thrustcub將啓動多個內核來完成此項工作,因爲內核啓動提供了方便的全局同步。

請注意,我們當然可以設計一個掃描,它具有「工作在比每個塊的線程更多的元素上」的獨立線程塊,但這並不能最終解決我們的問題(除非我們只使用1個線程塊),因爲我們必須啓動多個threadblocks充分利用硬件的優勢,並且在一般情況下多個線程塊引入了全局同步的必要性。

我提到的cub和thrust的實現都是開源的模板庫,所以如果你願意,你可以在那裏學習代碼(不是一件小事)。它們確實代表了CUDA專家設計和製造的高質量方法。您也可以在高水平研究他們的行爲很容易使用:

nvprof --print-gpu-trace ./mycode 

得到多少內核正在啓動和數據傳輸可能發生什麼快速閱讀,也可以使用nvvp,視覺分析器,研究這一點。

相關問題