终于意识到要开始自己整理一些知识了,为研究生的生涯做一些准备。本章为自学CUDA的一些关键知识点,主要来源于《GPU高性能编程 CUDA实战》
关于CUDA的一些资源,请见https://blog.csdn.net/taonull/article/details/49208703
CUDA™是一种由NVIDIA推出的通用并行计算架构,该架构使GPU(Graphics Processing Unit)能够解决复杂的计算问题。
安装流程跳过,直接看代码吧。
例子1
#include<iostream>
__global__ void kernel(void){ }
int main(void){
kernel<<<1,1>>>();
printf("hello,world\n");
return 0;
}
注:①CUDA C为标准C增加__global__修饰符,用来告诉编译器该函数是在GPU下运行
②kernel<<<1,1>>>为空函数kernel的调用,尖括号表示要将一些参数传递给运行时系统,这些参数并不是传递给设备代码的参数,而是告诉运行时如何启动设备代码。第一个参数表示GPU在执行核函数(kernel)时使用的并行线程块的数量,我们将每个并行执行环境称为一个线程块。如kernel<<<2,1>>>()即可理解为运行时将创建两个核函数的副本,并以并行方式运行他们。
例子2
基于GPU的矢量求和
#include ".."
#define N 10
__global__ void add(int *a,int *b,int *c)
{
int tid = blockIdx.x;
if(tid < N)
c[tid] = a[tid] + b[tid];
}
int main(void){
int a[N],b[N],c[N];
int *dev_a,*dev_b,*dev_c;
HANDLE_ERROR(cudaMalloc((void**)&dev_a, N * sizeof(int) ) );
HANDLE_ERROR(cudaMalloc((void**)&dev_a, N * sizeof(int) ) );
HANDLE_ERROR(cudaMalloc((void**)&dev_a, N * sizeof(int) ) );
for(int i=0;i<N;i++){
a[i]=-i;
b[i]=i*i;
}
HANDLE_ERROR(cudaMemcpy( dev_a, a, N * sizeof(int) ,cudaMemcpyHostToDevice) );
HANDLE_ERROR(cudaMemcpy( dev_b, b, N * sizeof(int) ,cudaMemcpyHostToDevice) );
add<<<N,1>>>(dev_a, dev_b, dev_c)
HANDLE_ERROR(cudaMemcpy( c, dev_c, N * sizeof(int) ,cudaMemcpyDeviceToHost) );
for(int i=0;i<N;i++)
{
printf("%d + %d = %d\n",a[i],b[i],c[i]);
}
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
return 0;
}
注:①cudaMalloc()是在GPU上为三个数组分配内存,cudaFree()是用于GPU使用完内存后释放
②cudaMemcpy()是实现CPU和GPU之间的数据转换,cudaMemcpyHostToDevice参数是将CPU -> GPU ,cudaMemcpyDeviceToHost参数是将GPU -> CPU
③并行的线程块的集合称为一个线程格,blockIdx.x值为线程格中的线程块号0~N-1,即为当前执行设备代码线程块的索引。
④HANDLE_ERROR()是定义的一个宏,用来判断函数调用是否返回一个错误值。
未完。。。