我一直在考慮如何使用約簡在CUDA上執行此操作,但是我對如何實現它有點不知所措。 C代碼如下。需要記住的重要部分 - 變量預計算值取決於兩個循環迭代器。另外,變量ngo對於每個值m ... 米 = 0,1,2可能具有NGO = 1,而米 = 4,5,6,7,8可以有NGO = 2,等等。我已經包括循環迭代器的尺寸的情況下它有助於提供更好的實施建議。嵌套循環中數組上的二維累積和 - CUDA實現?
// macro that translates 2D [i][j] array indices to 1D flattened array indices
#define idx(i,j,lda) ((j) + ((i)*(lda)))
int Nobs = 60480;
int NgS = 1859;
int NgO = 900;
// ngo goes from [1,900]
// rInd is an initialized (and filled earlier) as:
// rInd = new long int [Nobs];
for (m=0; m<Nobs; m++) {
ngo=rInd[m]-1;
for (n=0; n<NgS; n++) {
Aggregation[idx(n,ngo,NgO)] += precalculatedValue;
}
}
在先前的情況下,當precalculatedValue是內循環變量的僅一個功能,我在獨特數組索引保存的值,並與在事後並行還原(推力)加入它們。然而,這種情況讓我難堪:m的值不是唯一映射到ngo的值。因此,我沒有看到使這種代碼有效(甚至可行)使用減少的方法。任何想法都是最受歡迎的。
+1:「從簡單開始,測量性能,然後決定如何優化。」 - 一般的好建議,特別是像GPU這樣的東西。 – 2012-03-02 12:18:48
謝謝您的詳細解答!作爲第一步,我確定原始C算法輸出與循環移位相同。有各種計算都依賴於兩個迭代器,並且我沒有意識到我可以在不影響輸出正確性的情況下做這個簡單的更改。我會從這裏開始,如果atomicAdd給我一個合適的表現。 – 2012-03-02 15:45:05
但是我確實忘記了一個問題。 precalculatedValue(a,b)類型是雙重的。 (實際上它是一個具有2個double值的結構,所以操作重複兩次),我認爲這會造成性能瓶頸。 – 2012-03-02 16:40:46