作为英伟达针对N卡推出的通用并行计算平台和编程模型,CUDA类似于C语言的一种扩展,为应用程序和GPU硬件之间架起了桥梁。
CUDA在CPU、GPU异构计算系统上执行应用程序,将CPU及其内存称为Host,GPU及显存称为Device。一个典型的CUDA程序实现流程有以下三个部分。实际是Host程序与Device程序的交替执行。
1、把数据从CPU内存拷贝到GPU内存
2、调用核函数对存储在GPU内存中的数据进行并行操作
3、将GPU的运算结果拷贝回CPU内存
本文内容根据书本的介绍顺序,先从额内存管理和数据传输开始总结。
一、内存管理
异构计算中,CPU、GPU拥有着独立的物理内存。类似C语言中对CPU内存进行操作的malloc函数,在CUDA中也有一系列相应的内存操作。
C | CUDA | C | CUDA |
malloc | cudaMalloc | memset | cudaMemset |
memcpy | cudaMemcpy | free | cudaFree |
以cudaMalloc(void** devPtr, size_t size)为例,向Device分配指定大小的内存,返回一个指向该地址的指针。而cudaMemcpy用于数据在Host、Device的传输,利用指定参数确定传输方向。cudaFree与cudaMalloc成对使用。在CUDA6之后的统一寻址,我们此时尚不做总结,在书本的第四章内容有所介绍。
在GPU的内存结构中,最重要的是全局内存(global)和共享内存(shared),global相当于CPU中的系统内存,shared类似CPU的缓存,在软件层面,每一个block内的thread共享一块shared。
二、线程管理
在Device中,线程层次分为网格(grid),块(block),线程(thread)三级。一个核函数启动一个grid,一个grid中的所有thread共享global memary。一个grid中有多个block,一个block中有多个thread,grid和block可以有1d、2d、3d的组织结构,在核函数中,根据blockIdx和threadIdx将线程与数据对应一一映射。
关于核函数的申明以及调用,主要是__global__的限定符,用于Device的函数限定符__device__等等。此处不再展开,可以参考《CUDA C编程》30页的内容。