我對Cuda很新,我從書中閱讀了幾章,並在線閱讀了很多教程。我已經對矢量加法和乘法做了我自己的實現。是否可以使用CUDA來有效計算排序數組內的元素的頻率?
我想進一步移動一下,所以我們假設我們要實現一個函數,該函數將一個有序的整數數組作爲輸入。
我們的目標是找到數組中每個整數的頻率。
依次我們可以掃描陣列一次以產生輸出。時間複雜度將是O(n)
。
由於組別不同,我認爲必須有可能利用CUDA。
假設這是陣列
1
1
1
1
2
2
3
3
5
5
6
7
爲了實現完全並行,每個線程必須知道它是爲了找到和掃描陣列的到底是哪一部分。這隻有在我們使用另一個名爲int dataPosPerThread[]
的數組時才能實現,該數組對於每個線程標識dataPosPerThread[threadId]
將具有值作爲初始數組上的起始位置。所以,這意味着每個線程都會知道從哪裏開始以及在哪裏完成。
然而,這樣我們不會獲得任何收益,因爲它會花費我們O(n)
時間才能找到職位。最終總成本將爲O(n) + cost_to_transfer_the_data_to_the_gpu + O(c) + cost_to_transfer_the_results_to_the_gpu
其中O(c)
是線程找到最終輸出所需的常量時間,假設當然我們在初始數組內有許多不同的整數。
我想避免額外的O(n)
的成本。
什麼我想過到目前爲止,具有尺寸arraySize
的數組,我們指定要使用的線程的總量,假設totalAmountOfThreads
這意味着每個線程都有掃描totalAmountOfThreads/arraySize
值。
第一個線程(id 0)將從位置0開始掃描,直到位置totalAmountOfThreads/arraySize
。
第二個線程將從totalAmountOfThreads/arraySize + 1
開始依此類推。
問題是,某些線程可能正在使用不同的整數組,或者有一個組有更多的值正在被其他線程處理。比如在上面的例子,如果我們假設,我們將有6個線程,每個線程將採取2個達陣整數,所以我們有這樣的事情:
1 <-------- thread 0
1
1 <-------- thread 1
1
2 <-------- thread 2
2
3 <-------- thread 3
3
5 <-------- thread 4
5
6 <-------- thread 5
7
正如你可以看到線程0只1
值,但是線程2正在處理其他1
值。爲了實現並行性,這些線程必須處理不相關的數據。假設我們將使用這個邏輯,每個線程將計算結果如下:
thread 0 => {value=1, total=2}
thread 1 => {value=1, total=2}
thread 2 => {value=2, total=2}
thread 3 => {value=3, total=2}
thread 4 => {value=5, total=2}
thread 5 => {{value=6, total=1}, {value=7, total=1}}
有了這個結果有什麼方法可以進一步實現?有人可能會建議使用額外的hash_map,如unordered_map
,它可以有效地更新由單個線程計算的每個值的總變量。然而
Unordered_map
不被CUDA編譯器這將意味着線程將不能夠充分利用共享內存,因爲從不同的塊兩個線程可以用相同的價值觀來工作的支持,所以哈希映射必須位於全局內存中。
即使上述兩個問題沒有問題,我們在更新哈希映射時仍然會在線程之間存在競爭條件。
什麼是解決這個問題的好方法?
預先感謝您
它甚至可以有效地完成無序數據:http://www.moderngpu.com/sort/hist.html – tera 2013-04-10 00:07:43
該代碼似乎有點混淆,但我會研究它,但是我們可以利用的事實,即數組被排序以便以更簡單的方式產生結果? – ksm001 2013-04-10 00:16:29