2013-09-26 35 views
0

我無法使atomicAdd函數在所有區塊上工作。事實證明,以下內核代碼給我的線程總數的塊(< 5000爲例):跨區塊的CUDA atomicAdd

__global __ void kernelCode(float *result) 
{ 
    int index = threadIdx.x+blockIdx.x*blockDim.x; 
    if (index < 5000) 
    { 
     atomicAdd(result, 1.0f); 
    } 
} 

能否請你告訴我如何添加一些值,但沒有全陣列分配1.0f?這是因爲我在具有非常有限資源的系統上使用此代碼 - 每一個位都很重要。

+0

你的代碼工作正常..看看.. http://pastebin.com/daAGkZZu –

回答

1

此代碼可以跨多個塊工作,無需分配1.0f的數組。 if (index < 5000)聲明並不打算將您限制爲單個線程塊。它旨在確保只有整個網格中的合法線程參與操作。

嘗試這樣的事:

#include <iostream> 
#define TOTAL_SIZE 100000 
#define nTPB 256 

#define cudaCheckErrors(msg) \ 
    do { \ 
     cudaError_t __err = cudaGetLastError(); \ 
     if (__err != cudaSuccess) { \ 
      fprintf(stderr, "Fatal error: %s (%s at %s:%d)\n", \ 
       msg, cudaGetErrorString(__err), \ 
       __FILE__, __LINE__); \ 
      fprintf(stderr, "*** FAILED - ABORTING\n"); \ 
      exit(1); \ 
     } \ 
    } while (0) 

__global__ void kernelCode(float *result) 
{ 
    int index = threadIdx.x+blockIdx.x*blockDim.x; 
    if (index < TOTAL_SIZE) 
    { 
     atomicAdd(result, 1.0f); 
    } 
} 

int main(){ 

    float h_result, *d_result; 
    cudaMalloc((void **)&d_result, sizeof(float)); 
    cudaCheckErrors("cuda malloc fail"); 
    h_result = 0.0f; 
    cudaMemcpy(d_result, &h_result, sizeof(float), cudaMemcpyHostToDevice); 
    cudaCheckErrors("cudaMemcpy 1 fail"); 
    kernelCode<<<(TOTAL_SIZE+nTPB-1)/nTPB, nTPB>>>(d_result); 
    cudaDeviceSynchronize(); 
    cudaCheckErrors("kernel fail"); 
    cudaMemcpy(&h_result, d_result, sizeof(float), cudaMemcpyDeviceToHost); 
    cudaCheckErrors("cudaMemcpy 2 fail"); 
    std::cout<< "result = " << h_result << std::endl; 
    return 0; 
} 

您可以更改TOTAL_SIZE到任何數量將可以方便地貼合在float

注意,我在瀏覽器中輸入驗證碼,有可能是印刷錯誤。

+0

我跑你的代碼,但事實證明,結果是0,就好像內核函數沒有改變任何東西.. –

+0

我遺漏了正確的[cuda錯誤檢查](http://stackoverflow.com/questions/tagged/cuda?sort=frequent&pageSize=50)。你的設置可能有問題。不過,我已經測試了這個代碼,它在正確設置的機器中正常工作。我現在更新了代碼來做同樣的事情,但包括CUDA錯誤檢查。如果你編譯並運行它,你可能會知道什麼是錯的。您可能還想嘗試在命令提示符下運行'nvidia-smi -a',以瞭解GPU是否正確安裝並可用。 –

+0

嘿,我重新安裝了CUDA 5.5,它在VC++中工作,但是如果說TOTAL_SIZE大於這個數字,Mathematica會給出一個塊中的線程數量,因爲5000> 1024(允許的最大數量線程在一個塊中)。 –