2013-09-16 52 views
1

我會理解爲什麼結果是無窮大。我寫下面的代碼,我總是收到INF的結果。我的代碼有任何精度問題?無窮大導致雙操作

#include <stdio.h> 
#include <stdlib.h> 

#include "cuda.h" 
#include "curand_kernel.h" 

#define NDIM 30 
#define NPAR 5 

#define DIMPAR NDIM*NPAR 

__device__ double uniform(int index){ 
    return (double) 0.767341; 
} 


__global__ void iteracao(double *pos){ 

    int thread = threadIdx.x + blockDim.x * blockIdx.x; 
    double tvel; 
    int i = 0; 

    double l, r, t; 

    if(thread < DIMPAR){ 
     do{ 
      t = (double) uniform(thread); 
      l = (double) 2.05 * t * (pos[thread]); 
      r = (double) 2.05 * t * (pos[thread]); 
      tvel = (double) l+t+r; 
      pos[thread] = tvel; 
      i++; 
     }while(i < 10000); 
    } 

} 


int main(int argc, char *argv[]) 
{ 

    double *d_pos, *h_pos; 


    h_pos = (double *) malloc(sizeof(double) * DIMPAR); 


    cudaMalloc((void**)&d_pos, DIMPAR * sizeof(double)); 


    int i, j, k, numthreadsperblock, numblocks; 

    numthreadsperblock = 512; 
    numblocks = (DIMPAR/numthreadsperblock) + ((DIMPAR % numthreadsperblock)?1:0); 
    // 
    printf("numthreadsperblock: %i;; numblocks:%i\n", numthreadsperblock, numblocks); 

    cudaMemset(d_pos, 0.767341, DIMPAR * sizeof(double)); 
    iteracao<<<numblocks,numthreadsperblock>>>(d_pos); 
    cudaMemcpy(h_pos, d_pos, DIMPAR * sizeof(double), cudaMemcpyDeviceToHost); 

    printf("\n"); 
    for(i = 0; i < NPAR; i++){ 
     for(j = i*NDIM, k = j; j < (k+30); j++){ 
      printf("%f,", h_pos[j]); 
     } 
     printf("***\n\n"); 
    } 

    system("PAUSE"); 
    return 0; 
} 

輸出總是這樣:

numthreadsperblock:512 ;; numblocks:1

inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf inf,inf,inf,inf,inf,inf,inf,inf,*

inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf, Inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,*

inf,inf,inf,inf,inf ,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF,INF ,*

inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf, inf,inf,inf,inf,inf,inf,*

inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,*

+2

最有可能的是你將你的d_pos設置爲垃圾。 cudaMemset對字節值進行操作,並給出一個最可能導致零字節的浮點數。 – Anycorn

回答

1

您是初始的d_pos以錯誤的方式。 cudaMemset()只能逐字節地設置存儲器。有關更多詳細信息,請參閱cudaMemset() doc

要按照您的意圖初始化陣列,可以使用Thrust作爲快捷方式。

thrust::fill(
    thrust::device_pointer_cast(d_pos), 
    thrust::device_pointer_cast(d_pos) + DIMPAR, 
    0.767341); 
2

您有2個問題。第一個是@Anycorn在評論中描述的。 cudaMemset,就像memset需要一個字節值並設置字節位置。你不能用它來初始化float的值。

第二個是你的內核有一個循環,每個pos數組元素上運行10000次。實際上,您正在找到一個複雜表達式的10000階乘。由於這種表達總是積極的,你的回答就會爆炸。很可能你的內核寫得不正確。它沒有做你想做的事。即使您修復了第一個問題,並將pos正確初始化爲零,您的計算仍會爆炸。

您正在執行運算是:

pos[idx] = 0.767341 + (3.1460981 * pos[idx]); 

對於每個idx,要執行上述操作10000次。即使最初的pos[idx]值等於零,通過循環的第二次迭代,它也會以幾何形式開始起飛。