![](/img/trans.png)
[英]cuda shared memory, no synchronisation in kernel, premature output from kernel
[英]CUDA shared memory - sum reduction from kernel
我正在處理圖像多維數據集(450x450x1500)的大型數據集。 我有一個可以處理單個數據元素的內核。 每個數據元素產生6個中間結果(浮點數)。 我的塊包含1024個線程。 每個線程(6個浮點數組)將6個中間結果存儲在共享內存中。 但是,現在我需要將每個中間結果相加,以產生一個總和(6個總和值)。 我沒有足夠的全局內存來將這6個float數組保存到全局內存,然后從推力或宿主代碼中的任何其他庫中進行縮減。
共享內存中的數組上是否可以從內核函數內部調用任何還原例程?
解決這個問題的最佳方法是什么? 我是CUDA編程的新手,歡迎任何建議。
看完所有評論后,我了解到,您無需進行450x450x6倍的縮減,而不是進行1或幾次縮減。
在這種情況下,有一個更簡單的解決方案。
您無需為每個1500-D向量實施相對復雜的並行歸約。由於您已經有450x450x6個要歸約的向量,因此可以使用傳統的串行歸約方法並行縮減所有這些向量。
您可以使用具有16x16線程的塊來處理圖像的特定區域,並使用具有29x29塊的網格來覆蓋整個450x450圖像。
在每個線程中,您可以迭代1500個幀。 在每個迭代中,您可以先計算6個中間結果,然后將它們添加到總和中。 完成所有迭代后,您可以將6個和寫入全局內存。
這樣就完成了內核設計。 不需要共享的內存。
您會發現性能非常好。 由於這是內存綁定操作,因此它不會比只訪問一次所有圖像多維數據集數據長得多。
如果您沒有足夠的全局內存用於整個多維數據集,則可以將其分成[1500] [225] [225]的4個子多維數據集,然后在每個子多維數據集上調用內核例程。 您唯一需要更改的是網格大小。
看看這是徹底解釋了CUDA並行減少。
如果我正確理解,則每個線程應總結為“僅” 6
浮點數。
我不確定一般通過並行減少這樣做是否值得,因為您會獲得性能上的提升。
如果您以開普勒為目標,那么如果正確設置塊大小,以使中間結果以某種方式適合流多處理器的寄存器,則可以嘗試使用隨機播放操作。
正如羅伯特·克羅維拉(Robert Crovella)所指出的那樣,您關於存儲中間結果的可能性的陳述似乎很奇怪,因為全局內存的數量肯定大於共享內存的數量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.