几个你需要明白的定义
你应给能猜到,内存是CPU的草稿纸,显存是GPU的草稿纸。CPU和显卡都能够计算,他们各有优缺点。
通常,我们把CPU和内存的部分成为“主机”(Host),把先看成为“设备”(Device)。还记得那个简单的做加法的代码里面有个宏叫cudaMemcpyHostToDevice
吗?现在你应该知道cudaMemcpy
这个函数用这个宏做什么了吧?
我们可以近似地理解为,程序在“主机”上面串行运行,(尽管你的CPU可以是多核的,如果你擅长写多线程的程序最大化的使用CPU的性能那当然很好),在“设备”上面并行运行。
在“设备”上“并行”,这个“并行”的能力,完全不是CPU能够做到的。在同一时间,可能有上千个线程跑在显卡上,可能有几万个线程在等着调度。
先来看几个标识符:
__global__
:用来定义Cuda的入口函数,也成为内核函数或者核函数(不是Linux内核的意思)
__devide__
:用来定义被“设备”调用的函数
__host__
:用来定义被“主机”调用的函数
<<<1, 1>>>
:这两个我也不知道该怎么称呼的符号,
里面的两个参数,分别是线程格和线程块。
现在又回到几个定义来:
线程块:一个线程块由很多个线程组成。需要注意的是,线程块不是一个int整形这么简单,如果只是int,像上面的<<<1, 1>>>
,你可以把它当作是一维的,你也可以通过dim3()
函数把它定义成二维的或者三维的,至于要怎样做,关键是要怎样才能配合你的数据的结构。比如数组、矩阵、或者3D数据等等。
线程格:一个线程格包含有很多线程块,和线程块与线程的关系一样,线程格也是可以通过dim3
这个宏来定义的。至于dim3
这个宏如何使用,后面会讲到。