(一)CUDA开始
一、CPU和GPU的内部构成区别
CPU:叫做中央处理器(central processing unit)作为计算机系统的运算和控制核心,是信息处理、程序运行的最终执行单元。
可以形象的理解为有25%的ALU(运算单元)、有25%的Control(控制单元)、50%的Cache(缓存单元)。
因为CPU涉及到通用计算,复杂度较高。——总结成少量的复杂计算
GPU:叫做图形处理器。图形处理器(英语:Graphics Processing Unit,缩写:*GPU*),又称显示核心、视觉处理器、显示芯片,是一种专门在个人电脑、工作站、游戏机和一些移动设备(如平板电脑、智能手机等)上做图像和图形相关运算工作的微处理器。
可以形象的理解为90%的ALU(运算单元),5%的Control**(控制单元)、5%的Cache(缓存单元)**
GPU的设计原理:——总结为大量的简单运算
因此,CPU的计算量小,可计算复杂的运算,且对复杂运算的计算速度较快;而GPU计算量大,可计算简单的运算,且对复杂运算的计算速度较慢。但GPU对于大量简单运算的速度是远远快于cpu的,因为GPU的运算单元小且多,所以可以并行处理大量简单运算。
所以CPU 被设计成能够尽可能快地执行一系列操作(称为线程) ,并且能够并行地执行几十个这样的线程。GPU 被设计成能够并行执行数以千计的线程(缓冲较慢的单线程性能以获得更大的吞吐量)。
二、CUDA
NVIDIA 推出了 CUDA,这是一个通用的并行计算平台和编程模型,利用 NVIDIA 图形处理器中的并行计算引擎
比 CPU 更有效的方式解决许多计算问题。
CUDA: 一个在GPU 上计算的新架构CUDA(Compute Unified Device Architecture) 统一计算设备架构,在GPU 上发布的一个新的硬件和软件架构,它不需要映射到一个图型API 便可在GPU 上管理和进行并行数据计算。
CUDA 软件堆栈由几层组成,如图所示:一个硬件驱动程序,一个应用程序编程接口(API)和它的Runtime, 还有二个高级的通用数学库,CUFFT 和CUBLAS。硬件被设计成支持轻量级的驱动和Runtime 层面,因而提高性能。
三、CUDA编程模型
当通过CUDA 编译时,GPU 可以被视为能执行非常多的并行线程计算设备,它作为主机CPU 的一个协同处理器。
换句话说,运行在主机上的并行数据和高密度计算应用程序部分,被加载到GPU上。
为达到这个效果,这个函数被编译成设备的指令集(kernel
核函数),被加载到GPU。
//以下示例代码使用内置变量 threadIdx 将两个大小为 N 的向量 A 和 B 相加,并将结果存储到向量 C 中:
// Kernel definition
__global__ void VecAdd(float* A, float* B, float* C)
{
int i = threadIdx.x;
C[i] = A[i] + B[i];
}
int main()
{
...
// Kernel invocation with N threads
VecAdd<<<1, N>>>(A, B, C);//执行 VecAdd() 的 N 个线程中的每一个线程都会执行一个加法
...
}
CUDA C++ 通过允许程序员定义称为kernel的C++函数来扩展C++,当调用核函数时,由N个不同的CUDA线程并行执行N次,而不是像常规C++函数那样只执行一次。
使用 global 声明说明符定义核函数,并使用新的 <<<…>>> 执行配置语法指定内核调用的 CUDA 线程数。 每个执行内核的线程都有一个唯一的线程 ID,可以通过内置变量在内核中访问。
核函数只能在主机端调用,调用时必须申明执行参数。调用形式如下:
Kernel<<<Dg,Db, Ns, S>>>(paramlist);
• Kernel:定义的核函数名。
• <<<... >>>:内是核函数的执行参数,告诉编译器运行时如何启动核函数,用于说明内核函数中的线程数量,以及线程是如何组织的。
• 参数Dg:用于定义整个grid的维度和尺寸,即一个grid有多少个block, 为dim3类型
Dim3 Dg(Dg.x, Dg.y, 1)表示grid中每行有Dg.x个block,每列有Dg.y个block,第三维一般为1.
(目前一个核函数对应一个grid), 这样整个grid中共有Dg.x*Dg.y个block。
• 参数Db:用于定义一个block的维度和尺寸,即一个block有多少个thread,为dim3类型。
Dim3 Db(Db.x, Db.y, Db.z)表示整个block中每行有Db.x个thread,每列有Db.y个thread,高度为Db.z。
Db.x 和 Db.y最大值为1024,Db.z最大值为64。一个block中共有Db.x*Db.y*Db.z个thread。
• 参数Ns:是一个可选参数,用于设置每个block除了静态分配的shared Memory以外,最多能动态分配的shared memory大小,单位为byte。不需要动态分配时该值为0或省略不写。
• 参数S:是一个cudaStream_t类型的可选参数,初始值为零,表示该核函数处在哪个流之中。
• paramlist:定义核函数的参数。
关于CUDA threads详情请参考:(二) CUDA 编程模型概述-CSDN博客