NVIDIA A100 GPU的计算与内存层级结构
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领域的领跑者。点击订阅,与未来同行! 订阅:https://rengongzhineng.io/
NVIDIA A100 GPU的计算与内存层级结构,并探讨了影响其性能的关键因素,包括算术强度(Arithmetic Intensity, AI)、内存带宽、计算吞吐量以及程序设计策略。
在GPU中,计算速度远快于其访问主内存的速度。以NVIDIA A100为例,其在32位浮点操作上每秒可执行19.5万亿次操作(TFLOPS),而其主内存带宽约为1.5 TB/s。这种失衡意味着,在读取一个4字节数字的时间里,GPU原本可完成50多次计算。因此,内存瓶颈成为制约性能的主要障碍。
GPU计算单元称为“流多处理器”(Streaming Multiprocessor, SM),A100拥有108个SM,每个SM配备有共享内存(Shared Memory)、寄存器(Registers)等高速片上存储资源。每个线程(Thread)运行在SM中,线程们以32个为一组组成Warp,每个SM最多能容纳64个Warp、1024个线程。
共享内存和寄存器是SM片上的高速存储空间,分别用于线程块(Block)之间共享数据和单线程私有数据存储。共享内存带宽可达19.5 TB/s,寄存器访问速度更快(具体数值未公开)。相比之下,从全局内存(Global Memory)读写数据则通过相对缓慢的总线完成。
性能分析以“Roofline模型”为核心,该模型根据算术强度(AI)划分两种性能区间:
- 内存受限(Memory-bound):当AI低于13 FLOPs/Byte时,性能由内存带宽决定。
- 计算受限(Compute-bound):当AI高于13 FLOPs/Byte时,性能由计算能力决定。
通过对矩阵乘法(C = A@B)的两种策略分析发现,仅用寄存器直接从全局内存读取数据进行计算时,AI远低于13(如0.25、0.5 FLOPs/Byte),即为内存受限。提升AI的关键是数据重用:将多个线程合作从全局内存读取大块数据到共享内存中,再在共享内存中进行高效的重复利用。
在详细的分析中指出,为使加载效率最大化,线程需使用**合并访问(coalesced access)**策略,即一个Warp中所有线程读取一段连续128字节的数据。此外,向量化加载(vectorized loads)进一步提高效率,如使用float4一次读取4个float元素,并要求内存对齐。
另一方面,为解决B矩阵的列访问问题,该文提出共享内存转置加载策略(load-and-transpose):从全局内存行读取B的子块数据,并在写入共享内存时进行转置。这种策略既满足合并访问,又避免了共享内存中的银行冲突(bank conflict),即多个线程同时访问同一个内存模块时的性能下降问题。
在计算阶段,为了进一步提升AI并跨越计算边界,提出了让每个线程计算多个输出元素(如4x4子块)的策略。这种做法将计算块尺寸TILE_DIM增大(如从32提升至64),从而提高AI至16 FLOPs/Byte,超过了A100的临界点13,令内核转为计算受限。
此外,其他影响性能的关键因素:
- 线程块并发(Occupancy)与延迟隐藏:合理配置共享内存和寄存器使用量,使SM可同时调度多个线程块,提高Warp的调度选择范围,从而隐藏内存访问延迟。
- 线程分歧(Thread Divergence):Warp中线程执行路径不一致会导致序列化执行,降低吞吐率,建议使用分支无关的代码(如min/max替代if-else)以避免分歧。
- 量化(Quantization):使用较低精度(如FP16)可显著提升计算性能(如从FP32的19.5 TFLOPS跃升至FP16的312 TFLOPS),同时降低数据传输负担,双重提升AI。
最后,针对非整数倍Tile尺寸的问题,指出边界线程块会执行多余计算(如C += A * 0),但不会产生无效内存访问。尽管这种设计浪费部分资源,但保留了内核逻辑的统一性,避免了复杂的动态分支判断。
整体来看,该文通过详尽的理论与实践分析,为优化GPU程序、提升算术强度与整体性能提供了清晰的策略路径,特别适用于矩阵乘法等典型高性能计算任务的优化设计。