硬件通用

单核 CPU 实际是串行的

在单核 CPU 上,多线程的并发执行是通过上下文切换实现的假象。 实际上,任何一个时间点上,CPU 核心只执行一个线程的指令。 多线程的并行性是通过快速地在不同线程之间切换来实现的,切换速度快到足以让人感觉多个线程同时运行。

Compute Capability

Compute Capability 也称作 SM 版本。在应用中,通常会指定最低 Compute Capability 版本,告诉编译器,如果硬件支持的 Compute Capability 版本低于 6.0,那么将无法执行这个和函数。做法是使用 nvcc 时增加一个选项 nvcc -arch=sm_60。A100 SM 版本是7.5, H100 的SM 版本是8.0。

高版本的 Compute Capability 是低版本 Compute Capability 的超集。即高版本包含低版本所有性质和功能。

这里官方给出不同 SM 版本的细节信息,包括 warp 调度器 个数, https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#architecture-7-x

GPU 频率 和 传输带宽

处理器频率衡量的是处理器的速度,而带宽衡量的是数据传输速率。比喻:处理器频率快比作翻书的节奏快。存储器带宽大比作读完一页很快。两者需要匹配上,才能达到最佳效率。***

即:CPU/GPU 频率和带宽之间的关系是间接的。更高的 CPU/GPU 频率意味着处理器可以更快地处理数据,但这并不直接决定数据传输速度。带宽限制了 CPU/GPU 可以从内存或存储设备中读取数据以及将数据写入内存或存储设备的速度。如果带宽不足,即使 CPU/GPU 频率很高,性能也会受到限制,因为处理器必须等待数据传输完成。 因此,为了获得最佳性能,需要 CPU/GPU 频率和足够的带宽共同作用。

一个时钟周期 时钟频率

晶体管电路中时钟信号的一个完整振荡周期。它是芯片执行操作的最小单位。时钟周期的长度由时钟频率决定。比如翻书,一个时钟周期就是翻一页的时间。时钟周期越短,翻书的速度越快, 1 GHz 表示每秒 10 亿个时钟周期,每秒翻页10亿页书。

时钟周期 可以理解为计算机中最小的时间单位。计算机的时钟信号(Clock Signal)决定的,时钟信号是一个周期性的方波信号,它控制着计算机内部各个部件的操作节奏。***

时钟周期的长度取决于时钟频率。例如,如果时钟频率是1 GHz,那么每个时钟周期的长度就是1纳秒(ns)。时钟频率是硬件性能的重要指标。

存储器的理论带宽

  • 内存时钟速率(Hz):内存控制器每秒钟可以进行多少次数据传输操作。
  • 内存接口宽度(Byte):内存总线一次可以传输多少字节的数据。

上述两者相乘,得到理论带宽(Byte/s),相当于一个矩形,长乘宽,每秒钟可以传输的总字节数。*** 比如:

NVIDIA Tesla M2050 GPU 使用 DDR(双数据速率)RAM,具有 1,546 MHz 的内存时钟速率和 384-bit 宽的内存接口,那么GPU的现存理论带宽计算如下:

  • 内存时钟速率 (1546 MHz): 指的是 GPU 内存模块的数据传输速率。更高的时钟速率意味着 GPU 每秒可以从内存中读取或写入更多数据,从而提高性能。
  • 内存接口宽度 (384 位): 指的是 GPU 与其内存之间同时传输数据的位数。更宽的接口宽度意味着 GPU 可以一次性传输更多数据,

上述GPU显存理论带宽:1546,000,000 Hz * (384/8(Byte)) * 2 / 10^9 = 148 GB/s

存储器实际带宽

实际带宽 = ( ( Br + Bw ) ÷ 10^9 ) ÷ time

结果的单位是GB/s。Br表示每个kernel读取的字节数,Bw表示每个kernel写入的字节数。

比如,一个程序要计算一个float 类型的 2048*2048 的矩阵拷贝,整个过程的带宽:

实际带宽 = ( ( 2048 x 2048 × 4 × 2 ) ÷ 10^9 ) ÷ time

其中乘以 4 表示矩阵每个元素的类型是 float(4字节), 乘以2是因为由读写两个过程。最后除以 10^9 将最终单位转化为GB/s。

TOPS VS Tflops

  • TOPS:是Tera Operation per second,这些操作可以是整数、浮点数或其他类型的计算。
  • Tflops:是Tera floating point per second,表示浮点运算的性能。

对于线程的创建和调度所消耗的时钟周期,比较 CPU 和 GPU

CPUGPU
线程管理操作系统硬件
线程粒度重量级轻量级
时钟周期消耗数百至数千数个

线程粒度 体现了创建和销毁线程的开销

寄存器文件

是一个硬件组件,它包含多个寄存器,并提供对这些寄存器的快速访问。 它是集成在 CPU 或其他处理器芯片中。更准确地说,寄存器文件是多个寄存器组成的阵列,通常使用高速静态随机存取存储器 (SRAM) 实现,因为它比使用触发器阵列更紧凑。 它具有多个读写端口,允许处理器同时从多个寄存器读取数据并向多个寄存器写入数据,从而提高处理器的并行处理能力。

物理内存中的“页”

OS 以为粒度来管理物理内存。由于物理内存大小有限,在实际使用过程中,可能会将物理内存中的页换出到磁盘(然后在物理内存同一位置换入新的页)。

以页为粒度管理物理内存是一种常见的虚拟内存技术,它允许操作系统管理比物理内存更大的地址空间。在虚拟内存管理中,页 (Page) 是一个固定大小的内存块。操作系统将程序的地址空间划分为多个页,并将这些页存储在物理内存或磁盘上。页的大小通常是 2 的幂次方,例如4KB、8KB 或 16KB。

页面置换 (Page Replacement): 由于物理内存有限,当需要加载新的页到内存时,而内存已满,操作系统就需要选择一个或多个页从内存中换出到磁盘,腾出空间来加载新的页。这个过程称为页面置换。

页面置换算法有很多种,例如:

  • 先进先出 (FIFO): 将最早进入内存的页换出。简单易实现,但性能可能较差。
  • 最近最少使用 (LRU): 将最近最少使用的页换出。性能通常比FIFO好,但实现较为复杂。
  • 最不常用 (LFU): 将自加载以来使用次数最少的页换出。
  • 时钟算法 (Clock Algorithm): 一种近似LRU的算法,效率高,实现相对简单。

页面换入 (Page In): 当一个程序需要访问一个不在物理内存中的页时,操作系统会触发一个缺页中断 (Page fault)。操作系统会将该页从磁盘加载到物理内存中,然后继续执行程序。这个过程称为页面换入。

区别:

  • 页面置换 是腾出空间的动作,主动地从内存中移除页面。
  • 页面换入 是填充空间的动作,被动地将页面加载到内存中。

先腾出空间,再填充空间。

乱序执行

CPU 广泛使用乱序执行(OOE)。这意味着 CPU 并不一定按照程序代码的顺序执行指令。它会分析指令之间的依赖关系,并在不违反数据依赖的前提下,重新排列指令的执行顺序,以最大限度地利用 CPU 的资源,例如多个执行单元和缓存。例如,如果一条指令需要等待从内存中读取数据,CPU 可以先执行其他不依赖于该数据的指令,而不是空闲等待。乱序执行需要复杂的硬件支持:

  • 指令重排序缓冲区 (Reorder Buffer, ROB): 用于存放已解码但尚未提交的指令,并跟踪它们的执行状态和结果。
  • 寄存器重命名 (Register Renaming): 通过为寄存器创建多个副本,避免指令之间出现不必要的依赖关系,从而提高并行执行的效率。
  • 指令调度器 (Instruction Scheduler): 负责选择准备就绪的指令并将其分派到可用的执行单元。

GPU 通常不使用乱序执行。 相反,它们依赖于大规模并行性来实现高性能。GPU 拥有大量的核心,可以同时执行数千个线程。虽然每个线程内的指令通常是按顺序执行的,但由于线程数量众多,即使某些线程因为等待数据而停滞,其他线程仍然可以继续执行,从而保持 GPU 的高利用率。

DMA 硬件机制

DMA 通过绕过 CPU 直接进行数据传输,显著提高了数据传输效率和系统性能,尤其是在处理大量数据或实时性要求高的场景下。 它是一种重要的硬件机制,广泛应用于各种计算机系统和外设中(GPU 相对于 CPU 系统也是一个外设)。

DMA 工作机制的触发条件通常是:

  • 高数据吞吐量需求: 当需要在 CPU 和外设之间传输大量数据时,使用 DMA 可以显著提高效率。 CPU 不必逐字节地处理数据传输,可以专注于其他任务。 例如,从硬盘读取一个大文件,或者将视频帧数据传输到显卡。
  • 实时性要求: 在一些实时系统中,需要在严格的时间限制内完成数据传输,DMA 可以保证数据传输的及时性。 例如,控制工业设备或处理音频/视频流。
  • CPU 资源紧张: 当 CPU 负载较高时,使用 DMA 可以减轻 CPU 的负担,避免数据传输影响其他任务的执行。

CUDA 中如何使用 DMA

并行系统中负载均衡

系统中负载均衡:要求线程的执行时间尽量接近。如果不均衡,在需要线程同步时,所有线程会等待最慢的那个thread,此时整体的速度就时最慢的那个 thread 的速度,其他速度快的 threads 的优势完全没有了。