
核心判断:内核启动(kernel launch)只是把工作提交给 GPU;真正理解 CUDA,要沿着"发射 → 线程块(Block)驻留 → 线程束(Warp)调度 → 完成与同步"追踪它。① 为什么“能启动”还不够前文让线程找到了自己的坐标。接下来要回答一个更容易被忽略的问题:线程什么时候运行,运行在哪个流式多处理器(SM)上?CPU 函数调用通常在当前线程中执行,返回往往意味着函数已经完成。CUDA kernel 则不同:主机(Host)发射后,Host 线程通常可以继续执行,而 GPU 异步执行已经提交的工作。把这两种思维混在一起,是异步错误难以定位的根源。② 一条完整的执行链路这里的"异步"只描述主机(Host)与设备(Device)的推进关系,不代表 GPU 内部没有顺序。一个 Block 内的指令仍遵守 CUDA 的执行语义;只是不同 Block 的先后通常不应由程序假设。GPU 能同时驻留多少个 Block,取决于 SM 上可用的寄存器、共享内存(Shared Memory)和线程数等资源,因此一个 Grid 中的 Block 通常会分批驻留和执行。如下图所示,Grid 中的 Block 会被分配到可用的 SM 上执行;Block 一旦开始驻留,就在该 SM 上完成,而不是在多个 SM 之间来回迁移:这张图要观察的是“Block 到 SM”的映射关系:Grid 可以包含远多于 SM 数量的 Block,但同一时刻只有部分 Block 能驻留,前面的 Block 释放资源后,后续 Block 才能进入。③ 用%smid和%clock64让调度可见下面的最小示例让每个线程打印两个观察值:%smid可读取当前线程所在 SM 的编号,%clock64是设备侧时钟计数器。它们适合建立直觉,不是正式性能测量工具。#includecstdio#includecuda_runtime.h__global__voidobserve(){unsignedsmid;