2013-04-07 6 views
1

CUDA를 사용하여 베셀 함수 (예 : J0 (x))를 실행하려고합니다. 수식을 단정하십시오. enter image description here일부 엡실론 내에있는 BESSEL 함수

결과가 일부 엡실론 값 이내가되도록 노력합니다. 나는 그것이 검은 화면이 나타납니다 및 Windows는 엔비디아 드라이버가 응답하지 않았고 그것을 복구 있다고 실행하면 그래서 여기에 코드

__device__ void Bessel_j0(int totalBlocks, int totalThreads, float z, float epsilon, float* result){ 
      int n = 1; 
      *result = 0; 

      bool epsilonFlag = true; 

      int idx_start; 
      int idx_end; 

      while(epsilonFlag == true){ 
       initThreadBounds(&idx_start, &idx_end, n, totalBlocks, totalThreads); 
       float a_k; 
       for (int k = idx_start; k < idx_end; k++) { 
        a_k = m_power((-0.25 * z * z), k)/(m_factorial(k) * m_factorial(k)); 
        *result += a_k; 
       } 
       if(a_k < epsilon){ 
         epsilonFlag = false; 
       } 
       n++; 
      } 
     } 

__global__ void J0(int totalBlocks, int totalThreads, float x, float* result){ 
     float res = 0; 

     Bessel_j0(totalBlocks, totalThreads, 10, 0.01, &res); 
     result[(blockIdx.x*totalThreads + threadIdx.x)] = res; 
} 

__host__ void J0test(){ 

    const int blocksNum = 32; 
    const int threadNum = 32; 

    float *device_resultf; //для устройства 
    float host_resultf[threadNum*blocksNum] ={0}; 


    cudaMalloc((void**) &device_resultf, sizeof(float)*threadNum*blocksNum); 

    J0<<<blocksNum, threadNum>>>(blocksNum, threadNum, 10, device_resultf); 
    cudaThreadSynchronize(); 

    cudaMemcpy(host_resultf, device_resultf, sizeof(float)*threadNum*blocksNum, cudaMemcpyDeviceToHost); 

    float sum = 0; 

    for (int i = 0; i != blocksNum*threadNum; ++i) { 
     sum += host_resultf[i]; 
     printf ("result in %i cell = %f \n", i, host_resultf[i]); 
    } 
    printf ("Bessel res = %f \n", sum); 
    cudaFree(device_resultf); 
} 
int main(int argc, char* argv[]) 
{ 
    J0test(); 
} 

입니다. 그리고 콘솔 출력에는 host_resultf 배열에만 0이 있습니다. 뭐가 문제 야? 어떤 엡실론 안에서 제대로 기능을 수행하려면 어떻게해야합니까?

+1

프로그램 실행이 너무 오래 걸리고 Windows TDR 이벤트가 발생합니다. 그러면 프로그램 실행을 중단시키는 GPU 드라이버가 언로드됩니다. 프로그램에 논리 오류가있어 오랜 시간이 걸리거나 커널 실행을 단축 할 수 있는지 확인해야합니다. 또한 CUDA GPU가 Windows에서 디스플레이를 실행하는 WDDM GPU가 아닌 컴퓨터에서 실행해볼 수도 있습니다. WDDM GPU에서 실행되는 커널은 Windows TDR 이벤트를 시작하기 전에 약 2 초의 실행 시간으로 제한됩니다. –

+3

CUDA 라이브러리는 이미 두 번째 종류 y0, y1, yn의 베셀 함수뿐만 아니라 첫 번째 종류의 베셀 인 j0, j1, jn을 제공합니다. – njuffa

+0

@njuffa 그래, 나도 알아,하지만 나 혼자서 할 일이있어. -_- – DanilGholtsman

답변

1

커널 실행이 허용되는 커널 실행 시간 제한에 도달했을 수도 있습니다. 코드에는 반복 횟수에 대한 상한이 표시되지 않습니다. 엡실론에 결코 도달하지 않고 커널이 제한 시간을 초과하여 계속 실행되는 일이 발생할 수 있습니다. 이 site 도움이 될 수 있습니다.

모든 경우에 엡실론 루프에 상한을 추가하고 반복 횟수에 제한없이 코드를 실행하지 마십시오.

+0

와우, 그건 내가 생각하는 것보다 더 복잡해 질거야. – DanilGholtsman

관련 문제