参考自《GPU高性能运算之CUDA》主编:张舒。
1、主机与设备
CUDA编程模型将CPU作为主机(Host),GPU作为协处理器(co-processor)或者设备(Device)。在一个系统中可以存在一个主机或若干个设备。
CPU和GPU各司其职。CPU负责逻辑性较强的事物处理和串行计算,GPU则专注于执行高度线程的并行处理任务。CPU和GPU各自拥有相互独立的存储器地址空间:主机端的内存和设备端的显存。
并行计算函数称为kernel(内核函数)。一个kernel函数并不是一个完整的程序,而是整个CUDA程序中一个可以被并行执行的步骤。一个完整的CUDA程序由一系列的设备端kernel函数并行步骤和主机端的串行处理步骤共同组成的。
2、kernel函数的定义与调用
必须通过_global_函数类型符定义,并且只能在主机端代码中调用。在调用时,必须声明内核函数的执行参数。例如:
//Kernel定义
_global_ void VecAdd(float *A,float *B,float *C){
}
int main(){
//Kernel调用
VecAdd<<<1,N>>>(A,B,C);
}
VecAdd<<<1,N>>>(A,B,C)完成了对内核函数的调用。其中的<<<>>>运算符是内核函数的执行参数,用于说明内核函数的线程数量,以及线程好似如何组织的;小括号里的参数则是函数的参数。本例中,1,N是函数的执行参数,代表kernel的Grid中只有一个block,而每个block中则有N个thread;而A,B,C则是函数的参数。
注:不同计算能力的设备对线程的总数和组织方式有不同的约束。必须先为Kernel中用到的数组或变量分配好足够的空间,再调用kernel函数,否则在GPU计算时计算机会发生错误,例如越界或报错,甚至导致蓝屏或司机