Zhonghui

每个不曾起舞的日子,都是对生命的辜负

User Tools

Site Tools


程序:cuda:硬件细节

NV GPU硬件细节


主要硬件组成

模块 功能
SM(Streaming Multiprocessors) 执行核函数(Kernel)计算任务(即 compute)
Copy Engines(DMA Engines) 执行内存拷贝任务,如 Host ↔ Device,Device ↔ Device
Memory Controller 管理对 global memory(DRAM)的访问请求
PCIe/NVLink 接口 执行跨设备或主机拷贝

Streaming Multiprocessor(SM,流式多处理器)

  1. 每个 Streaming Multiprocessor(SM,流式多处理器) 上有多个 CUDA 核心。比如一个 SM 可能有 64、128 或更多 CUDA 核心(具体取决于架构)
  2. block(的各个线程)不是直接“映射”到核心上
  3. 当你创建一个 block(比如 1024 个线程),这些线程被分为若干个 warp(32 个线程一组)
    1. 每次只执行 一个或几个 warp,其余的等待调度
    2. SM 使用内部的 warp scheduler 按顺序调度这些 warp 到 CUDA 核心执行
    3. 总结:一个 block 最多可以有 1024 个“线程”,但这些线程是被调度到“共享的 CUDA 核心”上轮流执行的,而不是每个线程配一个核心
  4. 常见问题:所以threads数量和CUDA Core数量一致就能保证最大可能地利用硬件吗?不一定,threads过多过少都可能影响效率,好像没有一个一般性的选择标准?当然和warp数量(32)对齐是一定要保证的。
    1. 线程数越多(在1024的block上限内、且满足资源限制的前提下)通常越能让SM的计算核心得到更充分利用
    2. 一个block的线程越多:可以形成越多的warp(每32个线程一个warp),形成越多的warp可以提升指令发射覆盖延迟能力
    3. 但是线程调度也会带来性能消耗?每个线程都有寄存器分配、调度、上下文管理成本
    4. 让每个thread的计算“粒度”适中,即:不要太轻,不然你在浪费线程管理的成本;也不要太重,不然并行度不足
  5. SM内部是通过 warp-level 调度的:SM每个cycle可以调度多个warp执行指令
    1. 不同显卡(不同架构)的 SM 每个时钟周期可以调度的 warp 数量是不一样的
    2. 现代GPU(如Volta/Ampere)每个SM每周期能调度多个warp,而且调度器(warp scheduler)之间是并行工作
    3. 每 32 个线程组成一个 warp,warp scheduler 把 warp 分配给 CUDA Core 来执行
  6. 绝大多数现代NVIDIA架构,SM的CUDA Core数量和warp调度器数量是配套增长的。
    1. 一个warp调度器,通常负责一组32个CUDA Core。
    2. 比如,Volta/Ampere架构每个SM有64~128个CUDA Core,4个warp调度器。
    3. 4个调度器 × 32 Core = 128个Core,这样每个调度器都能每周期各自发射一个warp,所有Core都能被充分利用。
  7. SM里有多少Core,每个周期最多能干多少活,线程多了就是排队等着。
    1. 这就是为什么线程太多不会提升单个Block的性能,只会让排队时间变长。
    2. 但是合适增加warp数量可以更好地隐藏访存延迟,这是为什么推荐用1024线程/Block来提高SM利用率。
SM(Streaming Multiprocessor)
├── Warp Scheduler × N
├── CUDA Core × 64/128(FP32 ALU)
├── Special Function Units(SFU)
├── Load/Store Units(LD/ST)
├── Tensor Cores(如果有)
├── Shared Memory / L1 Cache

如何理解Streaming?「流」指的是什么?

  1. 首先,每个CUDA Core都是一样的,没有区别,不是CPU那样的流水线,有的取指令、有的计算之类的
    1. 在一个 SM 内的所有 CUDA Core,本质上是一组功能完全一样的 ALU(算术逻辑单元)。它们没有彼此之间的前后依赖关系,不存在“你处理前半,我处理后半”的流水线那种分工
    2. CUDA Core 之间是“平行关系”,而不是“前后关系”
  2. “Streaming”是逻辑概念,不是流水线关系
    1. 数据(线程)一批批地流入 CUDA Cores,按统一指令执行,然后流出,下一批继续
    2. 并不是流水线的流动,而是整体调度连续不断

CUDA核心

  1. CUDA 核心是 GPU 上执行浮点/整数运算的最小硬件单元(FP32 ALUs)
  2. 一个thread在一个CUDA Core上执行,一个warp = 32 threads

Copy Engines

  1. Kernel 计算 是由 SMs 执行的
  2. 数据 Copy(特别是异步的 cudaMemcpyAsync)则是由 DMA copy engine(也叫 Copy Engine) 完成的,不占用 SMs
  3. 二者可以并发执行,前提是你的 GPU 支持 deviceOverlap(使用cudaGetDeviceProperties查询)
  4. 虽然技术上 copy 和 kernel 可以并发,但也可能因为 共享资源(如 memory bandwidth) 导致性能下降:
    1. 同时进行大规模 copy 和计算时,可能发生 带宽争用
    2. 比如 copy 过程中 saturate 了 DRAM 带宽,kernel 访问 global memory 会变慢
  5. Copy Engine最多3个
    1. Host-to-Device、Device-to-Host、Peer-to-Peer 之间可以并发
    2. 但是某一个特定方向(比如Host-to-Device)内部不可并发(应该)
/var/www/DokuWikiStick/dokuwiki/data/pages/程序/cuda/硬件细节.txt · Last modified: 2025/07/15 06:18 by zhonghui