上午在CUDA中實現了Eratosthenes的篩選器,並且我有一個非常奇怪的輸出。我使用無符號字符*作爲數據結構並使用以下宏來操作這些位。CUDA中的位陣列
#define ISBITSET(x,i) ((x[i>>3] & (1<<(i&7)))!=0)
#define SETBIT(x,i) x[i>>3]|=(1<<(i&7));
#define CLEARBIT(x,i) x[i>>3]&=(1<<(i&7))^0xFF;
我定了位,以表示它是一個素數,否則就= 0 這裏是我打電話給我的內核
size_t p=3;
size_t primeTill = 30;
while(p*p<=primeTill)
{
if(ISBITSET(h_a, p) == 1){
int dimA = 30;
int numBlocks = 1;
int numThreadsPerBlock = dimA;
dim3 dimGrid(numBlocks);
dim3 dimBlock(numThreadsPerBlock);
cudaMemcpy(d_a, h_a, memSize, cudaMemcpyHostToDevice);
cudaThreadSynchronize();
reverseArrayBlock<<< dimGrid, dimBlock >>>(d_a, primeTill, p);
cudaThreadSynchronize();
cudaMemcpy(h_a, d_a, memSize, cudaMemcpyDeviceToHost);
cudaThreadSynchronize();
printf("This is after removing multiples of %d\n", p);
//Loop
for(size_t i = 0; i < primeTill +1; i++)
{
printf("Bit %d is %d\n", i, ISBITSET(h_a, i));
}
}
p++;
}
這裏是我的內核
__global__ void reverseArrayBlock(unsigned char *d_out, int size, size_t p)
{
int id = blockIdx.x*blockDim.x + threadIdx.x;
int r = id*p;
if(id >= p && r <= size)
{
while(ISBITSET(d_out, r) == 1){
CLEARBIT(d_out, r);
}
// if(r == 9)
// {
// /* code */
// CLEARBIT(d_out, 9);
// }
}
} 輸出應該是: 2,3,5,7,11,13,17,19,23,29 而我的輸出是: 2,3,5,9,7,11,13,17,19,23,29
如果你看看內核代碼,如果我取消註釋那些行,我會得到正確的答案,這意味着我的循環或檢查沒有任何問題!
此外,我會使用更大的單詞,如短褲或整數來存儲位數組,因爲「(如果讀取和寫入半換行中的線程可以合併爲32,64或128bytes,則訪問全局內存的速度最快)」 。 – 2011-03-17 14:31:59