2010-07-12 57 views
1

我在MS VS2005上使用CUDA SDK 3.1,GPU GTX465 1 GB。我有這樣一個內核函數:在CUDA中超時?/fermi/gtx465

__global__ void CRT_GPU_2(float *A, float *X, float *Y, float *Z, float *pIntensity, float *firstTime, float *pointsNumber) 
{ 


    int holo_x = blockIdx.x*20 + threadIdx.x; 
    int holo_y = blockIdx.y*20 + threadIdx.y; 

    float k=2.0f*3.14f/0.000000054f; 

    if (firstTime[0]==1.0f) 
    { 
    pIntensity[holo_x+holo_y*MAX_FINAL_X]=0.0f; 
    } 

    for (int i=0; i<pointsNumber[0]; i++) 
    { 
    pIntensity[holo_x+holo_y*MAX_FINAL_X]=pIntensity[holo_x+holo_y*MAX_FINAL_X]+A[i]*cosf(k*sqrtf(pow(holo_x-X[i],2.0f)+pow(holo_y-Y[i],2.0f)+pow(Z[i],2.0f))); 
    } 

    __syncthreads(); 


} 

,這是函數調用內核函數:

extern "C" void go2(float *pDATA, float *X, float *Y, float *Z, float *pIntensity, float *firstTime, float *pointsNumber) 
{ 
dim3 blockGridRows(MAX_FINAL_X/20,MAX_FINAL_Y/20); 
dim3 threadBlockRows(20, 20); 

CRT_GPU_2<<<blockGridRows, threadBlockRows>>>(pDATA, X, Y, Z, pIntensity,firstTime, pointsNumber); 
CUT_CHECK_ERROR("multiplyNumbersGPU() execution failed\n"); 
CUDA_SAFE_CALL(cudaThreadSynchronize()); 
} 

我加載在循環中的所有paramteres這個函數(例如4096元的每個參數一次循環迭代)。總而言之,我想在所有循環迭代之後爲每個參數創建32768個元素的內核。

的MAX_FINAL_X是1920和MAX_FINAL_Y爲1080

當我開始alghoritm第一次迭代中去非常快,經過一個或兩個迭代我越瞭解CUDA超時錯誤信息。我在GPU gtx260上使用了這個alghoritm,而且據我記得這樣做效果更好...

你能幫助我嗎..也許我在這個算法中根據新的費米拱進行了一些錯誤?

回答

1
  1. 這將是更好的調用 CUT_CHECK_ERROR cudaThreadSynchronize()後。由於 內核運行異步的,必須 等待結束瞭解 錯誤...內核也許在第二個迭代您收到第一個內核使用錯誤 。
  2. 確保 您在最感興趣的變量 pointsNumber[0](它可能會導致 長的內部循環)有一些有效數字。
  3. 也 可以提高你的內核 功能的速度:
    • 使用更好的塊​​。線程配置20x20會導致非常慢的內存使用率(請參閱編程指南和最佳做法)。嘗試使用塊16x16。
    • 不要使用pow(..., 2.0)功能。這是更快地使用SQR宏(#define SQR(x) (x)*(x)
    • 不要使用共享的紀念品,所以__syncthreads()不是必需的。

PS:您還可以傳遞值參數CUDA功能,不僅指針。速度將是相同的。

PPS:請改善代碼的可讀性......現在您必須編輯六個位置來更改塊配置......在內核中,您可以使用blockDim變量,並且可以在go2函數中使用常量。 你也可以使用bool firstTime - 它會更好,然後float

+0

我pointNumber [0]值有錯誤,而且您的線索加快這一alghoritm近2倍:d謝謝:) 我的第二個問題..它是可能的gpu的變化(從gtx260 896MB到gtx465 1GB)可能導致內存管理中的一些錯誤?在gtx260上,我可以分配500 * 500 * 500浮點數組(這是一種LUT數組),現在在gtx上,當我分配超過60 * 60 * 60浮點數組時,我得到錯誤「未指定的啓動錯誤」將數據從主機複製到設備內存(此memcopy不與該LUT數組連接)...? – Tome 2010-07-12 20:29:45

+0

很難說沒有代碼的東西......我在memcpy中看到過這樣的錯誤。這個錯誤與主機程序中的「分段錯誤」相同,併發生在內核中。 'CUT_CHECK_ERROR'讀取可能由較早的內核啓動引起的錯誤消息(如果您不使用'cudaThreadSynchronize')。只有4種異步operatioins: 1.內核啓動 2.所有cudaMemcpy *異步 3的memcpy設備<->設備 4.內存初始化 幾點建議: - 檢查'cudaMemcpy'參數。正確的順序和正確的內存分配(也許你忘了'cudaMalloc'?) - 使用emu模式來dbg。 – KoppeKTop 2010-07-12 21:09:51

+0

還有1個猜測。你是否將邊界檢查添加到內核? '如果(holo_x + holo_y * MAX_FINAL_X> = MAX_FINAL_X * MAX_FINAL_Y)回報;' 事實上,2倍 - 是不是限制) 如果要使用__constant__存儲器,用於存儲A,X,Y和Z +,也許移到快速數學(仔細)你會提供更多的加速。 – KoppeKTop 2010-07-12 21:20:12

1

是您的GPU連接到顯示器?如果是這樣,我相信默認情況是內核執行將在5秒後中止。您可以檢查內核執行是否會利用cudaGetDeviceProperties超時 - 見reference page

+0

是的,它連接到我的顯示器...... – Tome 2010-07-12 20:30:00

1

在你同樣的陣列,從中讀取寫入內核的週期 - 全球內存使用情況是最糟糕的,因爲從不同的塊經線互相等待。