CUDA8.0+VS2015快速上手与程序实例

    xiaoxiao2021-03-25  216

    CUDA8.0支持VS2015,系统支持MAC和LINUX和WIN,这里我用VS2015社区版来做开发。 安装教程多样雷同不做概述,只要 注意关闭杀毒软件和安装在默认目录就可以保证成功,装完后还要手动配置一下系统变量。 CUDA是支持c++/c语言,一般我喜欢用c来写,他的编译是gpu部分由nvcc来进行的 一般的函数定义  void   function(); cuda的函数定义 __global__ void function(); 解释:在这里,这个global前缀表明这个函数在哪里执行,可以由谁来呼叫 global:主机呼叫,设备执行 host:主机呼叫,主机执行 device:设备呼叫,设备执行 执行一般c函数   funtion(); 执行cuda函数   function<<>> (); 解释:在GPU上面执行函数可以自定分配grid和线程,grid包含线程,因为是并列执行,因此如果内容一样数据的生成很多是不分前后的。 运行例子的方法: 建立一个CUDA8.0 Runtim模版为基础的工程, 或建立一个c++工程,将cpp后缀改为.cu 无视任何应输入表达式这样的提示,该提示是编译器引起的 例1:一个简单的helloworld 体现grid和thread #include "cuda_runtime.h" #include "device_launch_parameters.h" #include #include cudaError_t addWithCuda(); __global__ void helloFromGPU(void) { printf("Hello World from GPU!\n"); } int main(void) { // hello from cpu cudaError_t cudaStatus; printf("Hello World from CPU!\n"); helloFromGPU << <1, 10 >> >(); cudaDeviceReset();//重置CUDA设备释放程序占用的资源 system("pause"); return 0; } 在这里 helloFromGPU << <1, 10 >> >(); 表示这一函数将有十个一样的线程,也就是这个函数总计会被执行十次。 改为 helloFromGPU << <2, 10 >> >(); 例2:一般的参数传入 传入参数与一般的c没有什么不一样之处 __global__ void Add(int i,int j) { int count; count = i + j; printf("\nNum is %d\n", count); } int main(void) { Add<<<1,1>>>(10, 15); cudaDeviceReset();//重置CUDA设备释放程序占用的资源 system("pause"); return 0; } 注:不可以定义为int类型 例3:数据的传入与传出 从这里开始要用到显存分配,在这一段中,我们的数据要从内存copy到显存上面,然后现在又要从显存上面copy回来 这次我们定一个减法函数,在设备上执行 __global__ void Decrease(int a, int b, int *c) { *c = a - b; } 我的要传的数为一个整数型的c 一般会定义一个全局的以cuda错误处理返回值为类型的函数,在这一函数内执行数据的传输,及时返回错误 cudaError_t   addWithCuda(int *c); 在例子中我省略了这个直接用void类型 void addWithCuda(int *c); 例子程序: void addWithCuda(int *c);//1.定义传入的函数c int main(void) { int c; c = 10;      addWithCuda(&c);//2.传入参数变量(地址) cudaDeviceReset();//6.重置CUDA设备释放程序占用的资源 printf("Value is %d", c);//7.主机上打印显示数据 system("pause"); return 0; } void addWithCuda(int *c) { int *dev_c = 0;//这个相当于内存和显存有一样的 //3.请求CUDA设备的内存(显存),执行CUDA函数 cudaMalloc((void**)&dev_c, sizeof(int)); Decrease << <1, 1 >> >(15, 30, dev_c); //4.等待设备所有线程任务执行完毕 cudaDeviceSynchronize(); / /5.数据复制到主机,释放占用空间 cudaMemcpy(c, dev_c,sizeof(int), cudaMemcpyDeviceToHost); cudaFree(dev_c); } 例4:数据的传入与传出 II 如果要复制数据进去,那么我们先要修改下上一个例子的函数 1.传入的数值全改为指针类型 __global__ void Decrease( int *a, int *b, int *c ) { *c = *a - *b; } 2.修改函数的传入参数 void addWithCuda(int *c,int *a,int *b);//1.定义传入的函数c 3.增加处理函数中对于相应存储空间的的申请和释放(彩色部分) void addWithCuda(int *c,int *a,int *b) { int *dev_c = 0; int *dev_a = 0; int *dev_b = 0; //3.请求CUDA设备的内存(显存),执行CUDA函数 cudaMalloc((void**)&dev_c, sizeof(int)); cudaMalloc((void**)&dev_a, sizeof(int)); cudaMalloc((void**)&dev_b, sizeof(int)); //4.从主机复制数据到设备上     cudaMemcpy(dev_a, a, sizeof(int), cudaMemcpyHostToDevice); cudaMemcpy(dev_b, b, sizeof(int), cudaMemcpyHostToDevice); Decrease << < 1,1>> >(dev_a, dev_b, dev_c); //5.等待设备所有线程任务执行完毕 cudaDeviceSynchronize(); //6.数据复制到主机,释放占用空间 cudaMemcpy(c, dev_c,sizeof(int), cudaMemcpyDeviceToHost); cudaFree(dev_c); cudaFree(dev_a); cudaFree(dev_b); } 4.最后是主函数 int main(void) { int c; int a, b; c = 10;  a = 30; b = 15; addWithCuda(&c,&a,&b);//2.传入参数变量(地址) cudaDeviceReset();//7.重置CUDA设备释放程序占用的资源 printf("Value is %d", c);//8.主机上打印显示数据 system("pause"); return 0; } 执行结果 后记: 1.太长时间没有写指针那一堆(这些对我来说是程序不稳定因素),总觉得名词都忘记的差不多,因此如果有误差的话我会修正。 2.内容基于网络参考而来,当然我觉得能够获得最大收益的还是自带的SAMPLE,内容新颖。 3.最近在啃两本书,一本是《GPU高性能编程CUDA实战》,例子讲的不错就是有点旧,需要一点变通总的来说是比较好使的,这本书还需要找到那个附带的book.h 头文件(后来我自己写了类似的)。 4.还有一本是《大规模并行处理器编程实战》,前期来看都在讲理论,后面再来做参考,内容进阶一点。
    转载请注明原文地址: https://ju.6miu.com/read-713.html

    最新回复(0)