我有一個非常簡單的算法,可以計算兩個矩陣的相應行之間的平方歐幾里德距離。我有以下代碼,但不幸的是,它不會爲不同的矩陣大小返回正確的結果。更具體地講,它工作正常大小2000x4
,500x4
,2500x2
,600x8
,1000x8
,100x8
的矩陣,但它是不工作的大小2500x3
,2500x5
,400x3
,100x3
,100x10
,1000x10
,1000x12
,500x12
,500x14
的矩陣。使用CUDA計算矩陣的相應行之間的歐幾里得距離
任何人都可以幫助我嗎?我想手動執行,而不使用任何優化庫,因爲我想了解線程管理。
__global__ void cudaEuclid(float* A, float* B, float* C, int rows, int cols)
{
int i, squareeucldist = 0;
int r = blockDim.x * blockIdx.x + threadIdx.x; // rows
int c = blockDim.y * blockIdx.y + threadIdx.y; // cols
extern __shared__ float sdata[];
//int r = blockIdx.y; int c = threadIdx.x;
if(r < rows && c < cols ){
//C[r + rows*c] = (A[r + rows*c] - B[r + rows*c]) * (A[r + rows*c] - B[r + rows*c]);
sdata[threadIdx.x] = (A[r + rows*c] - B[r + rows*c]) * (A[r + rows*c] - B[r + rows*c]);
__syncthreads();
// contiguous range pattern
for(int offset = blockDim.x/2;
offset > 0;
offset >>= 1)
{
if(threadIdx.x < offset)
{
// add a partial sum upstream to our own
sdata[threadIdx.x] += sdata[threadIdx.x + offset];
}
// wait until all threads in the block have
// updated their partial sums
__syncthreads();
}
// thread 0 writes the final result
if(threadIdx.x == 0)
{
C[r] = sdata[0];
}
}
}
內核調用是:
dim3 dimBlock(cols, 1);
dim3 dimGrid(1, rows);
cudaEuclid<<<dimGrid, cols, cols*sizeof(float)>>>(d_A, d_B, d_C, rows, cols);
PS:我想提一提,我已經發布了類似的問題,但它是從一開始就不清,討論是無所適從。儘管Tom提出了一個非常有用的建議,認爲未來優化實施將非常實用,但我需要更多的手工製作。最後,我發表這篇文章的原因是因爲我不想讓相關文章更加複雜。謝謝。
您測試過60x8嗎?或者您在60x5時停止了嗎?奇數列似乎沒有正確處理。或者甚至可能是2的給予'偏移>> = 1'的非冪... – chappjc
它正在爲60x8工作。 – Darkmoor
有道理,這就是問題所在,儘管Eric給出了一個完整的答案。 – chappjc