2010-07-12 4 views
1

MS VS2005에서 CUDA SDK 3.1을 GPU GTX465 1GB와 함께 사용하고 있습니다. 나는 그런 커널 기능이 있습니다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을 사용했는데 기억하는 한 더 잘하고있었습니다 ...

이 알고리즘의 새로운 Fermi 아치에 따르면 어쩌면 제가 실수를하고 있습니까?

답변

1
  1. cudaThreadSynchronize()CUT_CHECK_ERROR 전화를 더 좋을 것이다 참조하십시오. 커널이 비동기 적으로 실행되기 때문에 커널 종료를 기다려야합니다. 오류 ... 두 번째 반복에서 첫 번째 커널 사용에서 오류 가 표시 될 수 있습니다.
  2. 가장 흥미로운 변수 인 pointsNumber[0]에 올바른 숫자가 있는지 확인하십시오 ( 긴 내부 루프가 발생할 수 있음).
    • 를 사용하여 더 나은 블록 :
    • 또한 커널 기능의 속도를 향상시킬 수 있습니다. 스레드 구성 20x20은 매우 느린 메모리 사용을 유발합니다 (프로그래밍 안내서 및 모범 사례 참조). 16x16 블록을 사용해보십시오.
    • pow(..., 2.0) 기능을 사용하지 마십시오. SQR 매크로 (#define SQR(x) (x)*(x))를 사용하는 것이 빠릅니다.
    • 공유 메모리를 사용하지 않으므로 __syncthreads()은 필요하지 않습니다.

PS : 당신은 또한 CUDA 기능뿐만 아니라 포인터에 값 매개 변수를 전달할 수 있습니다. 속도는 동일합니다.

PPS : 코드의 가독성을 향상 시키십시오 ... 이제 블록 구성을 변경하는 6 개 위치를 편집해야합니다 ... 커널 내부에서 blockDim 변수를 사용할 수 있으며 go2 함수에서 상수를 사용할 수 있습니다. bool firstTime을 사용할 수도 있습니다. float보다 훨씬 좋을 것입니다.

+0

나는 또한 당신의 단서가 거의 2 시간이 alghoritm 속도를, pointNumber [0] 값에 실수를했다 gpu (gtx260 896MB ~ gtx465 1GB)의 변경으로 인해 메모리 관리에서 실수가 발생할 수 있습니다. gtx260에서 나는 500 * 500 * 500의 플로트 배열 (이것은 LUT 배열의 종류입니다)을 float에 할당 할 수 있었고 gtx에서 60 * 60 * 60 float 배열을 할당 할 때 "unspecified launch error"오류가 발생합니다. 호스트에서 장치 메모리로 데이터를 복사하십시오 (이 memcopy는 해당 LUT 배열과 연결되어 있지 않습니다) ...? – Tome

+0

코드 없이는 말하기가 매우 어렵습니다 ... memcpy 중에 새로운 오류를 보았습니다. 이 오류는 호스트 프로그램의 "Segmentation fault"와 동일하며 커널에서 발생합니다. 'CUT_CHECK_ERROR'는 이전의 커널 시작으로 인해 발생할 수있는 오류 메시지를 읽습니다 ('cudaThreadSynchronize'를 사용하지 않으면). cudaMemcpy''의 매개 변수를 확인 - : 1. 커널 출시 2. 모든 cudaMemcpy * 비동기 3. 방어 적이기 장치 <-> 장치 4. 메모리 초기화 조언 : operatioins 비동기 단지 4 종류가 있습니다. 올바른 순서와 올바른 메모리 할당 (아마도 'cudaMalloc'을 잊어 버린 것입니까?) - emu 모드를 사용하여 dbg를 만듭니다. – KoppeKTop

+0

그리고 1 더 추측. 커널에 경계 체크를 추가합니까? 사실, 2 회 - 제한이 아님) A, X, Y 및 Z +를 저장하기 위해 __constant__ 메모리를 사용할 경우 어쩌면 다음으로 이동하십시오. (예 : holo_x + holo_y * MAX_FINAL_X> = MAX_FINAL_X * MAX_FINAL_Y) 빠른 수학 (신중하게)을 좀 더 빨리 할 수 ​​있습니다. – KoppeKTop

1

GPU가 디스플레이에 연결되어 있습니까? 그렇다면 기본값은 5 초 후에 커널 실행이 중단된다는 것입니다. 당신은 커널 실행이 cudaGetDeviceProperties를 사용하여 시간 초과 여부를 확인할 수 있습니다 - reference page

+0

네가 내 디스플레이에 연결되어 ... – Tome

1

커널의 사이클에서 읽는 동일한 배열에 쓰는 것이 좋습니다. 전역 메모리 사용량이 가장 많은 것은 다른 블록의 워프가 서로 기다리기 때문입니다.이 가능하다 .. D 덕분에 :) 내가 두 번째 질문이 있습니다