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