G.6 融会贯通:向量处理器的性能
本节考察向量处理器的性能指标,以及这些指标能够反映哪些处理器特征。要确定处理器执行一个向量问题的性能,必须同时考虑启动开销与持续执行速率。报告向量处理器执行某个循环的性能时,最简单、也最好的方法,是给出该向量循环的执行时间。不过,人们往往以 MFLOPS——每秒百万次浮点运算——而非执行时间来表示向量循环性能。我们用 Rn 表示处理长度为 n 的向量时达到的 MFLOPS。只要浮点运算次数的计算口径一致,用 Tn(时间)或 Rn(速率)衡量就是等价的。无论采用哪一种,都应计入开销。
本节从不同角度分析 VMIPS 执行 DAXPY 循环(见第 4 章)的性能。我们仍使用 G.2 节建立的公式计算向量循环执行时间,同时考察如何根据算出的时间,以不同方式衡量性能。本节对 Tloop 采用常数,会引入少量误差,这里忽略不计。
向量性能的度量
向量长度对处理器性能影响很大,因此除了时间与 MFLOPS,还经常采用与长度有关的指标。这些指标在不同处理器之间往往相差很大,值得比较。不过请记住,比较两台处理器的相对速度时,最终关心的始终是时间。三个最重要的长度相关指标是:
- R∞:无限长向量的 MFLOPS。它可以用于估计峰值性能,但实际问题的向量长度有限,所承受的开销代价更大。
- N1/2:达到 R∞ 一半所需的向量长度。这是衡量开销影响的良好指标。
- Nv:使向量方式快于标量方式所需的向量长度。它既反映开销,也反映标量与向量的相对速度。
下面看看 VMIPS 执行 DAXPY 问题时的这些指标。采用链接时,DAXPY 内循环可以组织为图 G.10 所示的编队,假定 Rx 和 Ry 保存起始地址。
图 G.10 DAXPY 代码的内循环,按采用链接的编队组织。回顾包含 n 个元素的向量循环执行时间公式:
Tn=[MVLn]×(Tloop+Tstart)+n×Tchime链接使循环能够在 3 个 chime 中完成;由于只有一条存储器流水线,不能再少,因此 Tchime=3。如果 Tchime 足以完整反映性能,那么循环的浮点运算速率就应为时钟频率的 2/3,因为每次迭代执行两次浮点运算。仅根据 chime 数,不计 strip-mining 和启动开销时,500 MHz 的 VMIPS 可达到 333 MFLOPS。
有几种办法可以继续提高性能:增加向量加载—存储单元;允许编队重叠,以降低启动开销的影响;通过向量寄存器分配减少所需加载次数。本节考察前两项扩展。最后一项优化确实用于与 VMIPS 颇为接近的 Cray-1,使性能提高了 50%。减少加载次数需要过程间优化,习题 G.6 将讨论这种变换。分析前两项扩展之前,先来看看计入开销后的实际性能。
VMIPS 执行 DAXPY 的峰值性能
首先要确定真正的峰值性能 R∞,因为它必然不同于理想的 333 MFLOPS。暂时仍采用简化假设:只有前一编队中的全部指令完成,后一编队才能开始;后面再取消这一限制。在该假设下,向量序列的启动开销就是各条指令启动时间之和:
Tstart=12+7+12+6+12=49在性能公式中代入 MVL=64、Tloop=15、Tstart=49、Tchime=3,并假设 n 不是 64 的整数倍,可得处理 n 个元素的时间:
Tn=[64n]×(15+49)+3n≤(n+64)+3n=4n+64实际持续执行时,每次迭代需要超过 4 个时钟周期,而不是忽略开销时理论上的 3 个 chime。差异主要来自每 64 个元素的启动开销:启动需要 49 个周期,循环控制开销则为 15 个周期。
对于 500 MHz 时钟,现在可以计算 R∞:
R∞=n→∞lim(每次迭代的时钟周期数每次迭代的运算数×时钟频率)分子与 n 无关,因此:
R∞=limn→∞(每次迭代的时钟周期数)每次迭代的运算数×时钟频率n→∞lim(每次迭代的时钟周期数)=n→∞limnTn=n→∞limn4n+64=4R∞=42×500 MHz=250 MFLOPS不计启动开销、仅由向量功能单元结构决定的峰值性能,是这个结果的 1.33 倍。实际上,这项基准测试中峰值性能与持续性能的差距还会更大!
VMIPS 在 Linpack 基准测试上的持续性能
Linpack 基准测试对一个 100×100 矩阵执行高斯消元。因此,向量长度从 99 逐渐减至 1;长度为 k 的向量会使用 k 次。所以,平均向量长度为:
∑i=199i∑i=199i2=66.3现在可以用长度为 66 的向量,较准确地估计 DAXPY 的性能:
T66=2×(15+49)+66×3=128+198=326R66=3262×66×500 MFLOPS=202 MFLOPS忽略启动开销的峰值数值,是按实际向量长度估计的持续性能的 1.64 倍。实际上,Linpack 还有相当一部分代码不能向量化。虽然在向量化之前,这部分代码占执行时间不到 20%,但以浮点运算速率计,它的性能不到向量代码的十分之一。因此,根据 Amdahl 定律,整体性能会明显低于只分析内循环得到的估计。
由于向量长度显著影响性能,比较向量机时常使用 N1/2 和 Nv。
例题 对 500 MHz 的 VMIPS,如果只考虑 DAXPY 内循环,N1/2 是多少?
解答 把 R∞ 作为峰值速率,需要求出达到约 125 MFLOPS 的向量长度。假定测量处理 N1/2 个元素,从 MFLOPS 公式出发:
MFLOPS=N1/2 次迭代所需的时钟周期数N1/2 次迭代执行的浮点运算数×秒时钟周期数×10−6125=TN1/22N1/2×500化简,并假设 N1/2<64,此时执行时间为 64+3n,得到:
TN1/264+3N1/25N1/2N1/2=8N1/2=8N1/2=64=12.8因此 N1/2=13:在 VMIPS 上,长度为 13 的向量就能使 DAXPY 循环达到约一半的峰值性能。
例题 使向量操作快于标量操作的向量长度 Nv 是多少?
解答 同样知道 Nv<64。标量方式执行一次迭代的时间,可估为 10+12+12+7+6+12=59 个周期。其中 10 是循环控制开销的估计,比 strip-mining 循环的开销稍小。上一题已经得到,在 n≤64 时,这个循环以向量方式运行需要 Tn=64+3n 个时钟周期。因此:
64+3NvNvNv=59Nv=[5664]=2对 DAXPY 循环,只要向量至少有两个元素,向量方式就快于标量方式。这个门槛低得令人意外。
增强版 VMIPS 的 DAXPY 性能
DAXPY 和许多向量问题一样,受存储器限制。因此,增加访存流水线可以提高性能。这正是 Cray X-MP 及其后继处理器与 Cray-1 的主要体系结构差异。Cray X-MP 有三条存储器流水线,而 Cray-1 只有一条;X-MP 的链接也更加灵活。这会怎样影响性能?
例题 如果为 VMIPS 再增加两条存储器流水线,DAXPY 的 T66 会是多少?
解答 有三条存储器流水线时,所有指令都能放入同一编队,只需一个 chime。启动开销不变,因此:
T66=[6466]×(Tloop+Tstart)+66TchimeT66=2×(15+49)+66×1=194三条存储器流水线将持续执行所需周期数从 326 降至 194,带来约 1.7 倍的加速。注意 Amdahl 定律的影响:按 chime 数衡量的理论峰值速率提高至原来的 3 倍,但整体持续性能只提高至原来的 1.7 倍。
另一项改进是允许不同编队重叠,并让标量循环控制操作与向量指令重叠。这要求在前一向量操作尚未完成时,后一操作就可以开始使用功能单元,因此指令发射逻辑会更加复杂。这种重叠可以消除第一个编队之外各编队单独产生的启动开销,并隐藏循环控制开销。
要尽可能隐藏 strip-mining 开销,就需要让不同分段的循环实例重叠,使同一编队的两个实例,以及可能存在的两组标量代码同时执行。这需要使用第 3 章所述避免 WAR 冒险的技术;不过,由于不允许对同一个向量元素进行重叠读写,因此可以避免复制。这项技术称为 tailgating,Cray-2 曾使用过它。另一种办法是像第 3 章那样,展开外层循环,用不同寄存器组创建多个向量指令序列实例,前提是寄存器足够多。
让编队和标量循环控制操作尽可能重叠后,每个向量序列只会显现一次启动与循环开销,不再取决于编队数或各编队的指令数。这样,采用向量寄存器的处理器既能在短向量上获得较低的启动开销,也能在很长的向量上达到较高峰值性能。
例题 若为 VMIPS 再增加两条存储器流水线,并允许 strip-mining 与启动开销完全重叠,DAXPY 的 R∞ 和 T66 分别是多少?
解答
R∞=n→∞lim(每次迭代的时钟周期数每次迭代的运算数×时钟频率)n→∞lim(每次迭代的时钟周期数)=n→∞limnTn由于开销只显现一次,Tn=n+49+15=n+64。于是:
n→∞limnTn=n→∞limnn+64=1R∞=12×500 MHz=1000 MFLOPS增加访存流水线、采用更灵活的发射逻辑,使峰值性能达到原来的 4 倍。不过,T66=130,所以对较短向量,持续性能约提高至原来的 326/130=2.5 倍。
本节考察了几种向量性能指标。只根据 Tchime,就能计算理论峰值性能:
Tchime每次迭代的浮点运算数×时钟频率计入循环开销后,可以计算无限长向量的峰值性能 R∞,以及长度为 n 的向量的持续性能 Rn:
Rn=Tn每次迭代的浮点运算数×n×时钟频率还可以据此求出 N1/2 和 Nv,从另一角度观察向量启动开销,以及向量方式与标量方式的速度比。采用多种向量处理器性能指标,有助于理解应用实际可能获得的性能范围。