如果每个块中的线程数已经大于 CUDA 内核的数量,那么同时启动一个块网格是否比一次启动一个块有任何性能优势?
2 回答
我认为有;一个线程块被分配给一个流式多处理器 (SM),并且 SM 进一步将每个块的线程划分为 32 个线程的线程束(较新的架构可以处理更大的线程束),这些线程被调度为顺序执行(更多-更少)。考虑到这一点,将每个计算分成块会更快,以便它们占用尽可能多的 SM。这也意味着构建块是卡支持的每个线程的倍数的块(对于 SM 使用 32 线程线程的情况,一个块是 32 或 64 个线程而不是 40 个线程)。
启动延迟
启动延迟(在 GPU 上启动 API 调用)在 Linux 上为 3-8 µs,在 Windows Vista/Win7 上为 30-80 µs。
将一个块分配给一个 SM 需要 10-100s ns。
在一个块(32 个线程)中启动一个 warp 需要几个周期,并且在每个 SM 上并行发生。
资源限制
并发内核 - Tesla N/A 一次仅 1 个网格 - Fermi 一次 16 个网格 - Kepler 16 个网格(Kepler2 32 个网格)
最大块数(不考虑占用限制) - Tesla SmCount * 8 (gtx280 = 30 * 8 = 240) - Fermi SmCount * 16 (gf100 = 16 * 16 = 256) - Kepler SmCount * 16 (gk104 = 8 * 16 = 128)
有关每个块的线程、每个 SM 的线程、每个 SM 的寄存器、每个线程的寄存器等的限制,请参见占用计算器。
Warps 调度和 CUDA 核心
CUDA 核心是浮点/ALU 单元。每个 SM 都有其他类型的执行单元,包括加载/存储、特殊功能、分支等。一个 CUDA 内核相当于 x86 处理器中的一个 SIMD 单元。它不等同于 x86 内核。
占用率是每个 SM 的经线与每个 SM 的最大经线数的量度。每个 SM 的 warp 越多,warp 调度程序有一个合格的 warp 来调度的机会就越高。但是,占用率越高,每个线程可用的资源就越少。作为一个基本目标,您希望定位的目标超过
25% 特斯拉上 8 次经线 费米上 50% 或 24 次经线 开普勒上 50% 或 32 次经线(通常更高)
您会注意到在这些计算中与 CUDA 内核没有真正的关系。
To understand this better read the Fermi whitepaper and if you can use the Nsight Visual Studio Edition CUDA Profiler look at the Issue Efficiency Experiment (not yet available in the CUDA Profiler or Visual Profiler) to understand how well your kernel is hiding execution and memory latency.