繁体   English   中英

简单程序中的 CUDA 问题

[英]CUDA issue in a simple program

我花了这么多时间试图找出发生了什么? 问题是我无法从我的主机代码中调用这个简单的 kernel。 我敢肯定,对于某些人来说,这个错误会立即引起注意,但我觉得我可能毫无理由地浪费了很多时间。 所以我真的很感激任何帮助。

这是 my.cpp 代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <windows.h>
#include <shrUtils.h>
#include <cutil_inline.h>
#include <cutil_gl_inline.h>
#include <cuda.h>


CUfunction reduce0;    //i've used many ways to declare my kernel function,but.....


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

    int i,N,sum;
    int *data;
    int *Md;
    srand ( time(NULL) );
    N=(int)pow((float)2,(float)atoi(argv[1]));
    data=(int *)malloc(N * sizeof(int));

    for (i=0;i<N;i++){
        data[i]=rand() % 10 + 1;    
    }
    cudaMalloc((void**) &Md, N );

    clock_t start = clock();

    dim3 dimBlock(512,0);
    dim3 dimGrid(1,1);

    reduce0<<< dimGrid,dimBlock >>>(Md,Md);    



    sum=0;
    for(i=0;i<N;i++){
        sum=sum+data[i];
    } 

    printf("Sum of the %d-array is %d \n", N , sum);  
    printf("Time elapsed: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC);   

return 0;

}

这是 my.cu 代码

 __global__ void reduce0(int*g_idata, int*g_odata){

extern __shared__ int sdata[];

// each thread loadsone element from global to shared mem

unsigned int tid = threadIdx.x;
unsigned int i= blockIdx.x*blockDim.x+ threadIdx.x;
sdata[tid] = g_idata[i];

__syncthreads();

// do reduction in shared mem

for(unsigned int s=1; s < blockDim.x; s *= 2) {
if(tid % (2*s) == 0){
sdata[tid] += sdata[tid + s];
}

__syncthreads();
}

// write result for this block to global mem
if(tid == 0) g_odata[blockIdx.x] = sdata[0];
}

所以我问我应该怎么做才能调用kernel? 在编译时它不能识别这个符号“<<<”,并且就 reduce0() 而言,它只有在我声明 in.cpp 时才能识别它! 请有人帮我最终从真正的 cuda 开始!

CUfunction 是驱动程序 API 抽象 - 如果您要使用启用 kernel 调用的 <<<>>> 语法的语言集成功能,则不需要。

如果您不必使用驱动程序 API(大多数人不需要),只需将您的 C++ 代码移动到 .cu 文件中并调用 kernel 就像您现在所做的一样。

cudaMalloc()调用分配 CPU 无法读取或写入的设备 memory。 您必须使用cudaMemcpy(...,cudaMemcpyHostToDevice); 然后,完成处理后,使用cudaMemcpy(..., cudaMemcpyDeviceToHost);

ps 减少 kernel 非常慢。 我建议您打开还原 SDK 并从那里使用其中一个内核。

或者,使用将包含在 CUDA 4.0 中的 Thrust 库。 推力支持非常快速和灵活的减少。

调用 kernel 的代码必须由 NVCC 编译器处理。 (<<< 不是有效的 C++)通常意味着将其放入 .cu 文件中。 您不想将所有 cpp 代码移动到 cu 中(正如您在评论中所问的那样),只是调用 kernel 的代码。

改变

CUfunction reduce0;

void reduce_kernel(int*g_idata, int*g_odata);

并替换这些行:

dim3 dimBlock(512,0);
dim3 dimGrid(1,1);

reduce0<<< dimGrid,dimBlock >>>(Md,Md);  

和:

reduce_kernel(Md, Md);

并将其添加到 your.cu 文件中:

void reduce_kernel(int*g_idata, int*g_odata)
{
    dim3 dimBlock(512,0);
    dim3 dimGrid(1,1);

    reduce0<<< dimGrid,dimBlock >>>(g_idata, g_odata);  
}

这在我的脑海中,所以可能会稍微偏离,但你可以明白。

调用 kernel 的代码必须由 NVCC 编译器处理。 (<<< 不是有效的 C++)通常意味着将其放入 .cu 文件中。 您不想将所有 cpp 代码移动到 cu 中(正如您在评论中所问的那样),只是调用 kernel 的代码。

除了上述之外,我想我在你的 cudaMalloc 调用中发现了一个错误。 即使这不是一个实际的错误,我认为这是更好的可移植性编程实践。 它应该是:

cudaMalloc((void**) &Md, sizeof(int)*N);

If you are on a Windows machine, check the article for setting up Visual Studio 2010 for CUDA 3.2: http://www.codeproject.com/Tips/186655/CUDA-3-2-on-VS2010-in-9-steps .aspx

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM