英国物理学家开尔文勋爵曾说:“当你能够测量所谈论的对象,并用数字表达它时,你才算对它有所了解。”这句话出自他关于电学测量的演讲。

但在一次 GPU 性能测试中,数字没有带来答案,反而带来了疑问。我们测得的 Pixel Fill Rate只有规格值的一半,甚至更低。是 GPU 没有达到标称能力,还是测试本身测到了别的东西?

为了回答这个问题,我们开始逐一拆除测试中的干扰项:格式、混合、带宽、缓存、指令依赖……最终发现,准确测量的难点,不是得到一个数字,而是确认这个数字究竟代表什么。

这也成为我们建立 GPU 性能分析体系的第一步。

 

规格值与实际测量之间,差的是什么?

沿着这一疑问,我们进一步对多款 GPU 的 Pixel Fill Rate 实测结果与相应规格值进行了对照。在当前采用的测试配置下,部分实测值与规格值之间存在明显差异。

  某传统工具测试结果 规格值
  Pixel Fill Rate(Gpixels/s) Pixel Fill Rate(Gpixels/s)
显卡1 1.97 9.184
显卡2 3.24 7.2

表 1:特定测试配置下,多款 GPU 的 Pixel Fill Rate 实测值与规格值对比

注:本表用于展示测试条件对结果解释的影响,不用于产品性能排名。规格值与实测值的具体来源、频率口径和计算方法见测试说明。

从数据可以看出,实测值只有规格值的一半甚至四分之一。面对这种差异,我们首先需要避免一个过早的判断:实测值低于规格值,并不一定意味着 GPU 未达到标称能力,也不能直接说明测试工具本身存在问题。规格值通常描述特定条件下某个硬件单元的能力上限,而通用基准测试往往需要同时覆盖更完整的图形管线和应用行为,两者的测试目标与运行条件并不完全相同。

因此,在比较实测值与规格值之前,更重要的问题是:这两个数字是否采用了相同的定义、测试条件和计算口径?

以本次 Pixel Fill Rate 测试为例,进一步检查后,我们发现至少有两个值得关注的变量:

1)   渲染格式。测试使用的是 R16G16B16A16_FLOAT 格式,不同格式对应的单像素数据量和处理路径可能不同,因此测试结果也会不同。

2)   Blending操作。测试开启了融合操作,GPU 需要先从帧缓冲区读回SRC值(16bit × 4 通道),与新值做融合计算,再写回结果。与不开 blending 相比,处理路径可能不同。

 

如何让测试更接近它想测的东西

通用基准测试通常覆盖一条较为完整的执行路径。一个图形场景可能同时涉及顶点处理、光栅化、纹理采样、深度测试、混合和内存访问,最终给出帧率或执行时间等综合结果。

我们尝试换一个思路:不做加法,做减法。

核心思路是通过控制关键变量,让每一项测试更接近它想测的对象,并在明确记录的软硬件环境和测试条件下,验证结果的稳定性与可重复性。

 

  •   Pixel Fill Rate 像素填充率:极限减法

要单独测试Pixel Fill Rate,关键是控制其他因素的影响:

提高光栅化效率。绘制图元只选最简单的全屏三角形,减少顶点处理和图元组织开销,并以较简单的方式覆盖渲染目标。

1)关闭融合操作(blending)。减少对既有帧缓冲数据的读取及额外混合处理。

2)格式对齐。渲染目标采用 R8G8B8A8 格式,并在比较前确认该格式与所引用规格值的定义和计算口径具有可比性。

3)不加载纹理。让测试专注于纯像素填充能力。

这种“极限减法”的核心思想是:每控制一个非目标变量,就能减少一种可能的干扰,使测试结果更聚焦于目标处理路径。

 

  •   Texel Fill Rate 纹理填充率:缓存隔离带宽

纹理填充率的测试难点在于:纹理数据通常很大,很容易把测试变成带宽测试而非采样能力测试。解决思路如下:

1)用缓存隔离带宽的影响。选用 128×128 的小纹理(R8G8B8A8 格式),提高纹理数据缓存驻留概率。

2)每个像素同时采样并组合 8 张纹理,以提高纹理采样在整体负载中的占比,并尝试提升纹理采样单元的利用率。

当纹理数据足够小、缓存驻留概率提高时,测试受显存带宽限制的影响降低,使测试结果更侧重反映特定配置下纹理采样路径的可达吞吐。

 

  •   FP32浮点计算吞吐量:寄存器驻留,降低访存影响

测量着色单元 ALU 算力时同样面临干扰,如访存、指令依赖和运行频率等因素都可能影响结果。

为使测试更多地反映浮点执行路径的可达吞吐,我们采用以下方法:

1)通过让主要操作数驻留在寄存器中,降低片外访存延迟对浮点指令执行的影响。

2)使用高度紧凑的 FMA(乘加融合)指令。按照本文的计算口径,一条 FMA 包含一次乘法和一次加法,计为两次浮点运算。

3)为了防止FMA指令被编译器优化,使用两条FMA指令,a = a * b + b, b = b * a + a。重复执行这两条 FMA 运算以增加计算负载,并通过检查编译后的实际指令,确认目标运算未被消除或替换。

4)测试控制每个线程的寄存器使用量,并配置足够数量的并行线程,以提高执行单元的活跃线程规模,降低单条依赖指令延迟对整体吞吐的影响。实际并发度、寄存器使用和指令发射情况仍需结合编译结果及性能指标确认。

实测浮点计算吞吐量计算公式为:

每秒浮点运算次数 =

总线程数 * 单线程执行的有效FMA指令条数 * 2 / Kernel执行时间

 

本文中的微基准用于观察特定配置下 GPU 单项处理路径的可达吞吐。测试结果不等同于真实应用性能,也不能单独证明某个硬件单元已经达到其绝对物理上限。规格值与实测值的比较,需要建立在指标定义、数据格式、运行频率、运算计数和计时口径一致的基础上。

 

控制变量后的测试结果与讨论

基于上述设计思路,我们开发了RenderScope GPU性能测试工具, 在多张显卡上进行了测试,结果如下。

 

  •   Pixel Fill Rate 像素填充率测试结果

 

RenderScope测试结果

规格值

规格值使用率

 

Pixel Fill Rate (Gpixels/s)

Pixel Fill Rate (Gpixels/s)

测试结果/规格值

显卡3

9.05

9.184

98.54%

显卡4

56.41

56.86

99.21%

表 2:特定测试配置下,多款 GPU 的 Pixel Fill Rate 实测值与规格值对比

可以看到,在对齐部分测试条件并减少若干非目标因素的影响后,实测结果与规格值之间的差距有所缩小,部分显卡Pixel Fill Rate能达到规格值的98.54%。

 

  •   Texel Fill Rate 纹理填充率测试结果

 

RenderScope测试结果

规格值

规格值使用率

 

Texel Fill Rate (Gtexels/s)

Texel Fill Rate (Gtexels/s)

测试结果/规格值

显卡3

15.76

18.368

85.80%

显卡4

112.18

142.2

78.89%

表 3:特定测试配置下,多款 GPU 的 Texel Fill Rate 实测值与规格值对比

当前测试中部分显卡Texel Fill Rate 能到规格值的78.89%,虽然测试已经排除很多干扰因素,但是Texel Fill Rate 与规格值的差距还是有的,这里可能还涉及到其他干扰因素。

 

  •   FP32浮点计算吞吐量测试结果

 

RenderScope测试结果

规格值

规格值使用率

 

FP32(GFLOPS)

FP32(GFLOPS)

测试结果/规格值

显卡3

276.44

294

94.03%

显卡4

9390.06

9098

103.21%

表 4:特定测试配置下,多款 GPU 的 FP32 FLOPS 实测值与规格值对比

当前测试中FP32 FLOPS 测试结果与规格值很接近,但是存在部分显卡浮点测试结果超过了官方给的规格值,还需要进一步研究分析。

 

综合来看,调整测试条件后,部分指标的实测结果更加接近规格值,说明格式、流水线状态、数据驻留和指令组织等因素,确实会影响规格值与实测值之间的比较。不过,不同测试的结果并不完全一致,当前数据尚不足以对差异来源作单一归因。本文更希望说明的是:在讨论 GPU 是否达到规格能力之前,需要先确认规格值与实测值是否采用了可比的指标定义、测试条件和计算口径。控制变量能够提高结果的可解释性,但不能替代对剩余干扰因素和异常结果的持续验证。

 

从数字出发,但不止于数字

开尔文勋爵强调,测量并用数字表达,是认识一个对象的重要起点。但这次探索也让我们更加确信:有了数字,并不意味着已经理解了性能。只有说清楚这个数字测量了什么、在什么条件下成立,又受到哪些因素影响,它才真正具有解释价值。

建立可信的测量基线是 GPU 性能分析的第一步。接下来,我们还需要走进真实 workload,观察执行过程、定位性能瓶颈、验证因果关系,并最终将分析结果转化为软件优化和架构设计的依据。

一个数字不会自行讲述真相,但严谨的测量可以让它开始说话。