2013-03-23 84 views
1

在下面的代碼中,如何計算sum_array值而不使用atomicAdd如何在不使用CUDA原子的情況下進行總和計算

內核方法

__global__ void calculate_sum(int width, 
           int height, 
           int *pntrs, 
           int2 *sum_array) 
{ 
    int row = blockIdx.y * blockDim.y + threadIdx.y; 
    int col = blockIdx.x * blockDim.x + threadIdx.x; 

    if (row >= height || col >= width) return; 

    int idx = pntrs[ row * width + col ]; 

    //atomicAdd(&sum_array[ idx ].x, col); 

    //atomicAdd(&sum_array[ idx ].y, row); 

    sum_array[ idx ].x += col; 

    sum_array[ idx ].y += row; 
} 

啓動內核

dim3 dimBlock(16, 16); 
    dim3 dimGrid((width + (dimBlock.x - 1))/dimBlock.x, 
        (height + (dimBlock.y - 1))/dimBlock.y); 

回答

1

降低對於這類問題的通用名稱。請參閱presentation以獲得進一步說明,或使用Google進行其他示例。

解決此問題的一般方法是在線程塊內部創建並行總和的全局內存段並將結果存儲在全局內存中。之後,將部分結果複製到CPU內存空間,使用CPU對部分結果進行求和,然後將結果複製回GPU內存。您可以通過對部分結果執行另一個並行總和來避免對內存的處理。

另一種方法是對CUDA使用高度優化的庫,例如Thrust或CUDPP,其中包含執行這些功能的函數。

0

我CUDA是非常非常生疏,但是這是大概你如何做到這一點(「Cuda的用例」,我強烈建議您閱讀提供):

https://developer.nvidia.com/content/cuda-example-introduction-general-purpose-gpu-programming-0

  1. 對你需要總結的數組進行更好的分區:CUDA中的線程是輕量級的,但不是那麼多,以至於你可以只產生兩個總和,並希望獲得任何性能優勢。
  2. 在這一點上,每個線程都將負責總結一部分數據:創建一個與線程數量一樣大的共享int數組,其中每個線程將保存其計算的部分總和。
  3. 同步線程,減少共享內存陣列:

(請把它作爲

// Code to sum over a slice, essentially a loop over each thread subset 
// and accumulate over "localsum" (a local variable) 
... 

// Save the result in the shared memory 
partial[threadidx] = localsum; 

// Synchronize the threads: 
__syncthreads(); 

// From now on partial is filled with the result of all computations: you can reduce partial 
// we'll do it the illiterate way, using a single thread (it can be easily parallelized) 
if(threadidx == 0) { 
    for(i = 1; i < nthreads; ++i) { 
     partial[0] += partial[i]; 
    } 
} 

和您去:局部[0]會牽着你的總和(或計算)。

請參閱「CUDA示例」中的dot產品示例,以獲得關於該主題和約O(log(n))運行的約簡算法的更嚴格討論。

希望這會有所幫助

相關問題