简略CUDA和GPU相关概念
万物一齐,而百兽率舞。
本文简略介绍CUDA编程的相关背景
异构计算
首先,异构计算就是CPU+X,这个X可以是GPU,也可以是NPU,FPGA,DSP等等,在CPU上运行的代码称为Host主机代码,X上运行的代码称为Device设备代码
其次,异构计算和同构计算的一个不同点在于,异构的处理要比同构复杂,因为涉及同构下自动处理的计算,控制,传输都要人工进行干预
GPU
CPU vs GPU
先看cpu的架构和gpu架构的不同:
先看几个共同的部分:
- 控制器Control
- 缓存器Cache
- 随机存取存储器DRAM
- 总线PCIe Bus
- 算术逻辑单元ALU
不需要过多的计组原理知识,直观来看,GPU弱化了控制器的能力,大大堆砌了ALU的数量,且为一组ALU(SM,简单理解为线程束)分配了单独的Control和cache,所以直觉上,对了逻辑简单,数据量大的任务,GPU更高效
低并行逻辑复杂的程序适合用CPU
高并行逻辑简单的大数据计算适合GPUCPU和GPU线程的区别:
- CPU线程是重量级实体,操作系统交替执行线程,线程上下文切换花销很大
- GPU线程是轻量级的,GPU应用一般包含成千上万的线程,多数在排队状态,线程之间切换基本没有开销。
- CPU的核被设计用来尽可能减少一个或两个线程运行时间的延迟,而GPU核则是大量线程,最大幅度提高吞吐量
GPU简介
对于Nvida,GPU分为4个系列:
- Tegra
- Geforce
- Quadro
- Tesla
针对不同的应用场景,比如Tegra用于嵌入式,Geforce是平时打游戏用到,Tesla主要用于计算,但目前看Geforce和Tesla貌似也没那么分得很清楚,只是某些系列上有容错的硬件部分
GPU也存在版本号,即其计算能力,但这和性能不是成正比的,只代表架构的更新,对于CUDA来说,新版的cuda只支持最近几个版本的GPU,参考:https://en.wikipedia.org/wiki/CUDA#GPUs_supported
真正评价GPU能力的分为两种,一种是计算性能指标,一种是容量指标:
- 计算性能主要看FLOPS,一般单位在T级别(TFLOPS),称每秒浮点数运算次数,分单精度双精度,根据不同的架构,双精度一般是单精度的1/N
- 容量指标上有:显存,带宽,核心数量等,特别的如果一个CUDA程序爆显存了,则不使用统一内存的情况下是无法运行程序的
CUDA
CUDA平台不是单单指软件或者硬件,而是建立在Nvidia GPU上的一整套平台,并扩展出多语言支持
对于CUDA API来说,分为driver和运行时两种API,二者互斥不能同时使用,性能没啥差距
- driver API 低级,复杂,灵活,一般用于配合其他语言调用CUDA
- 运行时简单,基于driver API,稍微高级一点
CUDA编程环境架构如下:
nvcc
nvcc之于cuda相当于普通c++之于g++。因为cuda程序中host和device的代码是混在一起的,nvcc会分离这两个部分分别处理:
其中,PTX相当于CUDA的汇编语言
nvdia-smi
可以通过nvidia-smi(Nvidia's system management interface)程序检查与设置设备。它包含在CUDA开发工具套装内。
CUDA的程序结构
一般CUDA程序分成下面这些步骤:
- 分配GPU内存
- 拷贝内存到设备
- 调用CUDA内核函数来执行计算
- 把计算完成数据拷贝回主机端
- 内存销毁