2016-07-23 49 views
0

我開始閱讀「Cuda By Example」書籍,我一直在使用「共享內存」的點示例問題。我從書中複製粘貼示例,然後設置:N = x * 1024; threadsPerBlock = 32; blocksPerGrid = 8.其中我用2,3,4,5測試「x」值。 如果我設置x = 3,結果不好,但是當我使用x = 2,4,5時,一切正常。我不明白問題在哪裏。該代碼是:Cuda的點積產品通過示例不適用於我

#include "cuda_runtime.h" 
#include "device_launch_parameters.h" 
#include <stdio.h> 

#define imin(a, b) (a<b?a:b) 
#define sum_squares(x) (x*(x+1)*(2*x+1)/6) 

const int x = 3; 
const int N = 3 * 1024; 
const int threadsPerBlock = 32; 
const int blocksPerGrid = 8; 

__global__ void dot(float *a, float *b, float *c) 
{ 
    __shared__ float cache[threadsPerBlock]; 
    int tid = threadIdx.x + blockIdx.x * blockDim.x; 
    int cacheIndex = threadIdx.x; 
    float temp = 0; 

    while (tid < N) 
    { 
     temp += a[tid] * b[tid]; 
     tid += blockDim.x * gridDim.x; 
    } 

    cache[cacheIndex] = temp; 

    __syncthreads(); 

    int i = blockDim.x/2; 
    while (i != 0) 
    { 
     if (cacheIndex < i) 
      cache[cacheIndex] += cache[cacheIndex + i]; 
     __syncthreads(); 
     i /= 2; 
    } 

    if (cacheIndex == 0) 
     c[blockIdx.x] = cache[0]; 
} 

int main() 
{ 
    float *a, *b, *partial_c, result; 
    float *d_a, *d_b, *d_partial_c; 

    a = (float *)malloc(N * sizeof(float)); 
    b = (float *)malloc(N * sizeof(float)); 
    partial_c = (float *)malloc(blocksPerGrid * sizeof(float)); 

    cudaMalloc((void **)&d_a, N * sizeof(float)); 
    cudaMalloc((void **)&d_b, N * sizeof(float)); 
    cudaMalloc((void **)&d_partial_c, blocksPerGrid * sizeof(float)); 

    for (int i = 0; i < N; i++) 
    { 
     a[i] = i; 
     b[i] = 2 * i; 
    } 

    cudaMemcpy(d_a, a, N * sizeof(float), cudaMemcpyHostToDevice); 
    cudaMemcpy(d_b, b, N * sizeof(float), cudaMemcpyHostToDevice); 

    dot << <blocksPerGrid, threadsPerBlock >> >(d_a, d_b, d_partial_c); 

    cudaMemcpy(partial_c, d_partial_c, blocksPerGrid * sizeof(float),  cudaMemcpyDeviceToHost); 

    result = 0; 
    for (int i = 0; i < blocksPerGrid; i++) 
     result += partial_c[i]; 

    if (2 * sum_squares((float)(N - 1)) == result) 
     printf(":)\n"); 
    else 
     printf(":(\n"); 

    cudaFree(d_a); 
    cudaFree(d_b); 
    cudaFree(d_partial_c); 

    free(a); 
    free(b); 
    free(partial_c); 

    getchar(); 
    return 0; 
} 

回答

2

因爲float沒有足夠的精度,這是唯一~7 decimal digits。但對於x=3;您的預期結果是

19317916672 

包含11個數字。

對於x=4,5,結果在我的機器上也不好。

+0

好的,我改變了浮動倍數,工作正常。但我不明白爲什麼在我的情況下,x = 4,5(結果很大)沒有問題,但x = 3(較長的結果)失敗。 –

+0

@PavelAngelMendozaVillafane你可以打印你正在比較的兩個浮點數,以及精確的結果來查看原因。 '2 * sum_squares((float)(N - 1))'不一定會給'float'帶來正確的結果。 – kangshiyin

相關問題