簡體   English   中英

CUDA共享內存-內核的總和減少

[英]CUDA shared memory - sum reduction from kernel

我正在處理圖像多維數據集(450x450x1500)的大型數據集。 我有一個可以處理單個數據元素的內核。 每個數據元素產生6個中間結果(浮點數)。 我的塊包含1024個線程。 每個線程(6個浮點數組)將6個中間結果存儲在共享內存中。 但是,現在我需要將每個中間結果相加,以產生一個總和(6個總和值)。 我沒有足夠的全局內存來將這6個float數組保存到全局內存,然后從推力或宿主代碼中的任何其他庫中進行縮減。

共享內存中的數組上是否可以從內核函數內部調用任何還原例程?

解決這個問題的最佳方法是什么? 我是CUDA編程的新手,歡迎任何建議。

這似乎不太可能:

我沒有足夠的全局內存來將這6個float數組保存到全局內存,然后從推力或宿主代碼中的任何其他庫中進行縮減。

我無法想象您將如何有足夠的空間來將數據存儲在共享內存中,而不是在全局內存中。

無論如何, CUB提供了減少例程,可以從線程塊內調用該例程,並且可以對共享內存中存儲的數據進行操作。

或者,您可以編寫自己的總和減少代碼。 這並不是很難做到的,因此有很多關於此的問題,例如這個

或者,您可以修改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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM