关于cuda编程的一些问题

sand_and_fish 2012-12-18 04:09:21
小菜菜有几个关于cuda 的问题想请教一下:
1、请问大家在vs环境下,都是如何调试.cu文件的呢?
2、nvcc 具体的该怎么用呢?是直接在dos里面敲入命令就可以么?
3、memcheck的用法和存在的意义是什么呢?
4、最后呢,还有一个程序希望大家能帮我想想问题出在哪里呢?话不多说,下面先贴代码
cudaError_t addWithCuda(float *r, float *a, float *b, float *c, size_t size);

__global__ void addKernel(float *r, float *a, float *b, float *c)
{
int i = threadIdx.x;
int tem = a[i] + b[i];
tem=tem+c[i];
r[i]=tem;

}

int main()
{
const int arraySize = 1000;
float *a ;
float *b ;
float *c ;
float * r,*r1;
a=(float *)malloc(sizeof(float)*arraySize);
b=(float *)malloc(sizeof(float)*arraySize);
c=(float *)malloc(sizeof(float)*arraySize);
r=(float *)malloc(sizeof(int)*arraySize);
r1=(float *)malloc(sizeof(int)*arraySize);
for (int i=0; i<arraySize; i++)
{
a[i]=(float)i;
b[i]=1.0;
c[i]=1.;
r[i]=0.;
r1[i]=a[i]+b[i]+c[i];
}

// Add vectors in parallel.
cudaError_t cudaStatus = addWithCuda(r, a, b,c, arraySize);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "addWithCuda failed!");
return 1;
}
for (int i=0;i<arraySize;i++)
{
printf("%f+%f+%f=%f r1[i]:%f\n",a[i],b[i],c[i],r[i],r1[i]);
}
// cudaThreadExit must be called before exiting in order for profiling and
// tracing tools such as N sight and Visual Profiler to show complete traces.
cudaStatus = cudaThreadExit();
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaThreadExit failed!");
return 1;
}
free(a);
free(b);
free(c);
free(r);
free(r1);
return 0;
}

// Helper function for using CUDA to add vectors in parallel.
cudaError_t addWithCuda(float *r, float *a, float *b, float *c, size_t size)
{
float *dev_a = 0;
float *dev_b = 0;
float *dev_c = 0;
float *dev_r = 0;
int threadsNum=256;
int blockNum=(size+threadsNum-1)/threadsNum;
cudaError_t cudaStatus;

// Choose which GPU to run on, change this on a multi-GPU system.
cudaStatus = cudaSetDevice(0);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaSetDevice failed! Do you have a CUDA-capable GPU installed?");
goto Error;
}

// Allocate GPU buffers for three vectors (two input, one output) .

cudaStatus = cudaMalloc((void**)&dev_r, size * sizeof(float));
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMalloc failed!");
goto Error;
}
cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(float));
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMalloc failed!");
goto Error;
}

cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(float));
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMalloc failed!");
goto Error;
}

cudaStatus = cudaMalloc((void**)&dev_b, size * sizeof(float));
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMalloc failed!");
goto Error;
}

// Copy input vectors from host memory to GPU buffers.
cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(float), cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMemcpy failed!");
goto Error;
}

cudaStatus = cudaMemcpy(dev_b, b, size * sizeof(float), cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMemcpy failed!");
goto Error;
}
cudaStatus = cudaMemcpy(dev_c, c, size * sizeof(float), cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMemcpy failed!");
goto Error;
}

// Launch a kernel on the GPU with one thread for each element.
addKernel<<<blockNum, threadsNum>>>(dev_r, dev_a, dev_b,dev_c);

// cudaThreadSynchronize waits for the kernel to finish, and returns
// any errors encountered during the launch.
cudaStatus = cudaThreadSynchronize();
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaThreadSynchronize returned error code %d after launching addKernel!\n", cudaStatus);
goto Error;
}

// Copy output vector from GPU buffer to host memory.
cudaStatus = cudaMemcpy(r, dev_r, size * sizeof(float), cudaMemcpyDeviceToHost);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMemcpy failed!");
goto Error;
}

Error:
cudaFree(dev_c);
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_r);

return cudaStatus;
}


这段代码的问题在于:输出的结果不正确,或者说,数据个数较少的时候是正确的,但是数据数据多一点就会发生错误,这是为什么呢?
下面是程序的运行结果:

最后一列的r1的值是cpu跑出来的正确的结果
...全文
379 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
yjoe61 2012-12-25
  • 打赏
  • 举报
回复
cuda-memcheck <memcheck参数> <你的程序> <你的程序的参数> 可以查你程序里有没有非法访问之类的。
cc19851 2012-12-21
  • 打赏
  • 举报
回复
nvcc 会调用 cl,就是vs使用的编译器。 装完toolkit和sdk后,vs就会和cuda集成,也就是加入了cuda的规则文件,这时cu文件会默认调用nvcc进行编译,所以vs可以直接编译cuda程序,但是有的依赖项需要你自己设置,如头文件目录,附加库目录,也就是命令行下的 -I,-L。 如果windows下开发的话,基本不需要在命令行下make
cc19851 2012-12-20
  • 打赏
  • 举报
回复
1.直接就可以调试 2.nvcc就是编译器,使用和gcc,icc类似 3.没用过 4.int i = threadIdx.x; ---〉int i = blockIdx.x*blockDim.x+threadIdx.x; if(i<size)
sand_and_fish 2012-12-20
  • 打赏
  • 举报
回复
引用 2 楼 cc19851 的回复:
1.直接就可以调试 2.nvcc就是编译器,使用和gcc,icc类似 3.没用过 4.int i = threadIdx.x; ---〉int i = blockIdx.x*blockDim.x+threadIdx.x; if(i<size)
我还是不是特别明白,第二个问题哎,没有用过gcc,都是直接vs自带的编译器的呀 编程能力不太好,问的问题太白了呀,惭愧惭愧呢
sand_and_fish 2012-12-18
  • 打赏
  • 举报
回复
哪位大神来回复一下吧

231

社区成员

发帖
与我相关
我的任务
社区描述
CUDA on Windows XP
社区管理员
  • CUDA on Windows XP社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧