GPU具备强大的并行计算能力,但有时性能瓶颈并不源于数据饥饿,而是来自指令饥饿。本文通过一个真实的基因组学应用案例,深入介绍如何识别指令缓存未命中问题,并演示通过调整循环展开策略来消除瓶颈、提升性能的完整方法。
一、问题背景:一个看似正常的GPU工作负载
在基因组学领域,有一个常见任务:将DNA样本的小片段与参考基因组进行比对。该任务基于Smith-Waterman算法,由大量小而独立的问题组成。在NVIDIA H100 Hopper GPU(拥有114个SM)上运行该程序时,使用NVIDIA Nsight Compute (NCU)工具分析,发现SM虽然在执行有用计算,但存在性能问题。
组成整体工作负载的许多小问题(每个问题由自己的线程处理)可以同时在GPU上运行,因此并非所有的计算资源都一直被完全使用。这表现为一个非整数数量的波。GPU的工作被划分为线程块,一个或多个线程块可以驻留在SM上。如果某些SM接收到的线程块较少,它们将先完成工作,而其他SM仍在运行,导致空闲。
什么是“波”与“尾部效应”
- 波:用线程块完全填满所有SM构成一个波。NCU会报告每个SM的波数。
- 尾部效应:如果波数不是整数(例如100.5),意味着部分SM工作量较少,被迫闲置。当波数较小(如0.5)时,这种不均衡占比很大,导致严重性能损失。
