2016-09-26 2 views
-3

addAtomic이 예상대로 작동하지 않는 상황이 있습니다. 나는 cuda에 대해 매우 익숙해 졌기 때문에 무언가를 놓치고 있지만, 거의 좋은 하루 동안이 일에 매달려서 메모리 할당 문제로 생각되는 대부분의 다른 프로그램을 재 작성했습니다. 이 doesnt는 경우 인 것처럼 보인다.cuda, addAtomic 이상한 결과 생성

기본적으로 발생하는 것은 데이터의 최소/최대 및 합계 값을 생성해야하는 '분석'커널을 호출한다는 것입니다. 동일한 데이터가 합계로 min/max에 사용됩니다. 그러나 atomicadd 연산의 결과는 메모리 주소처럼 읽습니다. 매우 큰 숫자. 제가 누락 된 것이 있습니까? 저는 이것을 백 번 넘게 끝 냈고 min/max와 sum을 제외하고 커널에서 거의 모든 것을 제거했습니다.

__global__ void analyze(int *data, int *min, int *max, int *mean) 
{ 
    int t_id = (threadIdx.x * AXIS_COUNT) + blockIdx.x; 
    int b_id = blockIdx.x; 

    int localVal = data[t_id]; 
    atomicMin(&min[b_id], localVal); 
    atomicMax(&max[b_id], localVal); 
    atomicAdd(&mean[b_id], localVal); 
} 
    ........... 
    int r; 
    int step = WINDOW_LENGTH * AXIS_COUNT; 
    for (r = 0; r < out_rows; r++){ 
     analyze<<<AXIS_COUNT, WINDOW_LENGTH>>>(
               &d_data[r * step], 
               &d_min[r * AXIS_COUNT], 
               &d_max[r * AXIS_COUNT], 
               &d_mean[r * AXIS_COUNT]); 
    } 

    cudaDeviceSynchronize(); 

    cudaMemcpy(h_min, d_min, int_size, cudaMemcpyDeviceToHost); 
    cudaMemcpy(h_max, d_max, int_size, cudaMemcpyDeviceToHost); 
    cudaMemcpy(h_mean, d_mean, int_size, cudaMemcpyDeviceToHost); 
    for(r=0; r < out_rows; r++) { 
     fprintf(stderr, "mean %d, x: %d, y: %d z: %d\n", r, h_mean[r*AXIS_COUNT], h_mean[r*AXIS_COUNT + 1], h_mean[r*AXIS_COUNT+2]); 
    } 

결과 형태이다 :

mean 5025, x: 2078310793, y: 1999653847 z: -1453684997 
mean 5026, x: 2078308025, y: 1999646363 z: -1453660854 
mean 5027, x: 2078305391, y: 1999639383 z: -1453636904 
mean 5028, x: 2078304342, y: 1999630356 z: -1453613212 

I은 ​​검증 및 확인 관련 문서와 최소/최대 값을 확인 하였다.

+0

CUDA는 ** 아닙니다 ** C! – Olaf

+2

'd_mean'을 0으로 초기화 한 부분을 표시하지 않았습니다. [Minimal, Complete, Verifiable example] (http://stackoverflow.com/help/mcve)를 게시하십시오. – tera

+0

@tera : 나는 근본 원인이라고 확신하지만, 누가 알겠는가 .... – talonmies

답변

-3

대답은 커널의 공유 메모리를 초기화하는 것이 었습니다.

__shared__ double sum[AXIS_COUNT]; 
    if (threadIdx.x == 0) { 
     int i; 
     for (i=0; i < AXIS_COUNT; i++) 
      sum[i] = 0; 
    } 


    syncthreads(); 
    int t_id = (threadIdx.x * AXIS_COUNT) + blockIdx.x; 
    int b_id = blockIdx.x; 
+1

질문의 커널에 공유 메모리 사용이 없습니다. 그렇다면 공유 메모리를 초기화하면 어떻게 될까요? – talonmies