核函数(Kernel)
1.在GPU上执行的函数通常称为核函数。
2.一般通过标识符__global__修饰,调用通过<<<参数1,参数2>>>,用于说明内核函数中的线程数量,以及线程是如何组织的。
3.以线程格(Grid)的形式组织,每个线程格由若干个线程块(block)组成,而每个线程块又由若干个线程(thread)组成。
4.是以block为单位执行的。
5.叧能在主机端代码中调用。
6.调用时必须声明内核函数的执行参数。
7.在编程时,必须先为kernel函数中用到的数组或变量分配好足够的空间,再调用kernel函数,否则在GPU计算时会发生错误,例如越界或报错,甚至导致蓝屏和死机。
/* * @file_name HelloWorld.cu 后缀名称.cu */
#include <stdio.h> #include <cuda_runtime.h> //头文件
//核函数声明,前面的关键字__global__ __global__ void kernel( void ) { }
int main( void ) { //核函数的调用,注意<<<1,1>>>,第一个1,代表线程格里只有一个线程块;第二个1,代表一个线程块里只有一个线程。 kernel<<<1,1>>>(); printf( "Hello, World!\n" ); return 0; }
|
dim3结构类型
1.dim3是基亍uint3定义的矢量类型,相当亍由3个unsignedint型组成的结构体。uint3类型有三个数据成员unsigned int x; unsignedint y; unsigned int z;
2.可使用亍一维、二维或三维的索引来标识线程,构成一维、二维或三维线程块。
3.dim3结构类型变量用在核函数调用的<<<,>>>中。
4.相关的几个内置变量
4.1.threadIdx,顾名思义获取线程thread的ID索引;如果线程是一维的那么就取threadIdx.x,二维的还可以多取到一个值threadIdx.y,以此类推到三维threadIdx.z。
4.2.blockIdx,线程块的ID索引;同样有blockIdx.x,blockIdx.y,blockIdx.z。
4.3.blockDim,线程块的维度,同样有blockDim.x,blockDim.y,blockDim.z。
4.4.gridDim,线程格的维度,同样有gridDim.x,gridDim.y,gridDim.z。
5.对于一维的block,线程的threadID=threadIdx.x。
6.对于大小为(blockDim.x, blockDim.y)的 二维 block,线程的threadID=threadIdx.x+threadIdx.y*blockDim.x。
7.对于大小为(blockDim.x, blockDim.y, blockDim.z)的 三维block,线程的threadID=threadIdx.x+threadIdx.y*blockDim.x+threadIdx.z*blockDim.x*blockDim.y。
8.对于计算线程索引偏移增量为已启动线程的总数。如stride = blockDim.x * gridDim.x;threadId += stride。