2011-06-30 85 views
1

在CUDA中執行此操作的最佳方法是什麼?用cuda代替c for循環

... 
for(int i=0;i<size;++i)                    
    for(int j=i+1;j<size ;++j)                   
    temp_norm+=exp((train[i]-train[j])/tau); 

這是否等同?

... 
int i = threadIdx.x + blockIdx.x * blockDim.x; 
int j = threadIdx.y + blockIdx.y * blockDim.y; 

if (i>=size || j>=size) return; 

if(j>i) 
    temp_norm+=exp((train[i]-train[j])/tau); 

任何幫助將不勝感激!

回答

2

如何最好地實施取決於size有多大。但假設它非常大,例如1000或更多...

要做到這一點你建議,你需要使用atomicAdd(),如果太多的線程原子地添加到相同的地址,這可能是昂貴的。更好的方法可能是使用並行縮減。

查看NVIDIA CUDA SDK中的"reduction"示例。

YMMV與以下,因爲它未經測試,我不知道你的數據大小,但這樣的事情應該工作。使用該示例中的「reduction6」內核,但將計算添加到第一個while循環。更換的i初始化和gridSize

unsigned int i = blockIdx.x*blockSize + threadIdx.x; 
unsigned int gridSize = blockSize * gridDim.x; 

與更換while (i < n)

while (i < size) 
{ 
    for (unsigned int j = i+1; j<size; ++j) 
     mySum += exp((train[j]-train[i])/tau); 
    i += gridSize; 
} 

(注意,浮點運算是不相關的,所以在並行執行不同的操作順序可能會與順序實現相比,你的答案略有不同,由於平衡樹的減少,它可能會給你一個更準確的答案,這取決於你的輸入數據。)