第2节 CPU性能论
如果汽车的进步周期能同步计算机的发展周期的话,今天一辆劳斯莱斯仅值100美元,每加仑可跑100万英里。
——Robert X. Cringely,技术作家
[注:1加仑(gal)≈4.5L,1英里(mile)≈1.6km]
龙芯CPU性能提升路线
CPU怎样运行软件?
计算机 = 程序 + 存储
计算机系统由硬件和软件组成。硬件是指物理实体,包括电子设备和机械设备。软件是指在硬件上面存储和处理的信息,本身没有物理实体。
生活中还能找到很多类似的硬件和软件。电视机本身是硬件,而电视机播放的节目是软件。U盘是硬件,而U盘上存储的文档、音乐、电影、游戏是软件。
CPU显然属于硬件,而CPU上运行的程序属于软件。硬件和软件是怎样配合工作的呢?下面以一个最简单的计算机的例子来展示,如图1.6所示,这个计算机的功能为“汉字生成器”,代号为CHN-1型。
图1.6 CHN-1型计算机
存储器(M)保存了连续的二进制编码序列,每一个单元会保存0或1,分别代表要在显示屏上输出的汉字是“关”或“开”。这样的一个二进制单元代表了计算机要执行的一项独立的操作,称为“指令”。多个指令构成一串连续执行的操作,称为“指令队列”,也称为“程序”。
控制器(CC)在一个时钟模块的驱动下工作。时钟模块以一定频率向控制器发出信号,这个频率称为计算机的“主频”。每次这个信号到来时,控制器内部的地址计数器会增加1。地址计数器的内容发送给存储器中的数据选择器,数据选择器会把指令队列中对应该地址的单元内容发送给控制器,并保存在控制器内部的一个存储单元中。控制器内部的存储单元称为“寄存器”。由于从存储器中取出的数据代表指令,因此这个单元称为“指令寄存器”。
运算器(CA)在这台计算机中是一个汉字点阵生成器。控制器把指令寄存器中的内容发送给运算器,运算器根据输入的指令是0还是1,输出对应汉字“关”或“开”的点阵。每个汉字用8×8的点阵来表示,每个点叫作“像素”。运算器的输出是64位二进制数据,保存在控制器的另外一个存储单元中。由于运算器的输出属于计算结果的数据,因此这个单元称为“数据寄存器”。
输入设备(I)包含两个开关。其中一个开关连接着一个固定输出“0”的模块,使用者按下开关后,会把一个常量0输出到控制器的指令寄存器中,覆盖存储器中读出的指令。另外一个开关用于固定输出“1”。这样的输入设备给使用者提供了干预程序运行的手段,作用类似于实际计算机的键盘、鼠标。
输出设备(O)是一个8像素×8像素的汉字显示器,从控制器的数据寄存器中获取64位汉字点阵,根据每一位的0、1值决定每一个像素的亮、灭,表现为汉字的“关”或“开”。
上述5个部件联合工作,使得整个计算机按照时钟频率切换显示器的汉字内容。
CPU由控制器、运算器两部分组成,所运行的软件就是存储器中的指令队列,软件的执行结果体现为计算机显示的汉字信息。如果想要改变计算机显示的汉字信息,只需要修改存储器中的指令队列,而不用修改计算机的硬件,计算机运行模型如图1.7所示。
图1.7 计算机运行模型
虽然这个计算机运行模型极为简单,但是它已经体现出电路硬件怎样存储和执行软件。归根到底,软件无非是0和1组成的序列,而硬件是能够“理解”0和1的数字电路,硬件能够对0和1进行存储、传送、加工,因此软件世界和硬件世界能够衔接起来。
虽然计算机内部使用0和1的二进制,但是在输出到计算机外部时可以转换成方便人类理解的自然表示方式,例如以汉字显示,这样又把计算机世界和人类世界衔接起来了。
这个模型还体现出了冯·诺依曼体系结构的基本思想:计算机 = 程序 + 存储。程序输入计算机中,计算机能够自己指挥自己工作,不再像之前的机器一样需要工人来操作。计算机的出现大幅提升了自动化水平,这是划时代的革命。
主频越高,性能就越高吗?
有很多种方法造出“主频低、性能高”的计算机
为了正确认识计算机的性能,首先要定义性能的实质含义。性能可以用“计算机在单位时间内完成多少计算量”来衡量。
主频是CPU工作的时钟频率,是计算机的一个重要参数。对于一台计算机来说,主频越高,显然计算机在单位时间内能完成的工作就越多。仍然以前文所述的精简计算机模型CHN-1为例,通过提高时钟模块的频率,可以提升CPU的主频,这意味着汉字切换速度更快。宏观上看,在一段时间内有更多的汉字得到显示。
但是,任何计算机中的主频都不是无限提升的。在晶体管电子计算机中,数据从一个模块传输到下一个模块是需要时间的,运算器中进行的数据加工处理也是需要时间的,计算机运行流程如图1.8所示。所有数据通路上的传输时间,再加上运算器的加工处理时间,决定了执行每一条指令的最短时间,也决定了计算机正常工作的最高主频。如果时钟频率过高,会导致一条指令还没执行完,下一条指令又在等待处理,计算机会进入不可控状态。
图1.8 计算机运行流程
采用更先进的半导体生产工艺,可以提高芯片内晶体管的密度,减少数据传输的最小时延,这是突破最高主频瓶颈的一种方式。
但是主频并不是性能的唯一决定因素。我们同样可以造出一台“主频低、性能高”的计算机CHN-2。工程师可以在以下方面改进设计。
(1)输出设备扩容,能够同时显示4个8像素×8像素的汉字。
(2)存储器中的指令队列扩容,每条指令由1位改成4位,每条指令保存的是4个“开”或“关”命令。
(3)控制器中的指令寄存器也扩容到4位,每次能够从存储器中读取4条指令。
(4)运算器中的汉字点阵生成器扩充为4个,能够同时转换4个汉字的点阵。
(5)控制器中的数据寄存器由64位改为256位,把4个汉字点阵输出到显示器。
改进后的CHN-2计算机有什么优点呢?CHN-1每次显示一个汉字,是“串行”计算机;而CHN-2能每次处理4个汉字,是“并行”计算机,如图1.9所示。CHN-2的主频可以低于CHN-1,例如只有CHN-1主频的1/4,但是在相同时间内CHN-2显示的汉字数量与CHN-1是相同的,所以CHN-2与CHN-1的性能也是相同的,这样就推翻了“主频高的计算机性能一定高”的论断。
上面展示的CHN-2的例子,是通过增加硬件并行度来提升计算性能的典型方法。
图1.9 串行处理和并行处理
需要注意的是,CHN-2性能的提升,是建立在增加成本的基础上的。CHN-2每一条指令包含的汉字数量是CHN-1的4倍,这意味着CHN-2指令包含的内容信息更丰富了,用专业术语说就是“单条指令的语义更强”。CHN-2必须提高各个组成部分的硬件处理能力,包括提高队列容量、增加数据通路宽度、增加加工单元个数,这些都将增加设计难度,也使各个部分的晶体管数量成倍增长。
为什么MIPS和MFLOPS不能代表性能?
单位时间内执行的指令数量不能体现性能
早期的计算机主要用于科学计算,衡量性能的指标有“每秒执行的百万级机器语言的指令数量”(Million Instructions Per Second,MIPS),以及“每秒执行的百万级机器语言的浮点指令数量”(Million Floating-point Operations per Second,MFLOPS)。从定义来看,这两个指标只关注单位时间内执行的指令数量,比较适用于高性能计算机这种计算模式单一的场景。
但是MIPS和MFLOPS的定义有固有的缺陷。不同的计算机中,每一条指令所代表的功能含义是不同的,例如CHN-2的一条指令所显示的汉字信息是CHN-1的4倍。所以单纯用指令数量是无法体现计算机的性能的。
现在MIPS和MFLOPS只在很狭窄的高性能计算机领域得以沿用。
面向问题的性能评价标准:SPEC CPU
性能的真正含义是在更短的时间内解决问题
现在业界更多地采用“面向问题”(Problem-oriented)的性能评价标准。它的基本思想是从实际生活中挑选一些有代表性的计算问题,再在计算机上使用软件解决这些问题。软件运行的时间越短,则计算机的性能越高。
面向问题的性能评价标准屏蔽了计算机本身的硬件参数,不再考虑主频、指令这种实现层面的因素,所得出的结果更符合性能的本质意义——计算机在单位时间内完成多少计算量,因此得到广泛接受。
国际上使用的计算性能测试工具有SPEC CPU,其网站如图1.10所示。这个工具从典型的实际应用中抽取几十个计算问题,涉及的领域有文件压缩、国际象棋求解、有限元模型、分子动力学、大气学、地震波模拟,等等。对每一个问题,使用高级程序语言编写了标准的计算软件,并且规定好输入数据。使用高级程序语言的好处是,软件代码用C语言、Fortran等和CPU无关的语言编写,能够在任何计算机上运行。
图1.10 SPEC CPU网站
在被测试的计算机上,使用编译器对SPEC CPU软件进行编译,并且运行一次,如果计算机得出了正确结果,那么运行时间越短则代表计算机的性能越高。国际知名的CPU企业都会把测试结果提交到SPEC CPU网站上(spec.org),供外界公开查询。
随着计算机的发展,SPEC CPU工具也持续升级,先后在2000年、2006年、2017年推出新版本。例如,早期版本的数据量非常小,在当前的计算机上很快运行就结束了,因此新版本增大了测试集的输入数据量;早期版本只测试一个CPU,而现在的计算机都包含多个CPU,因此后来又支持了多个CPU同时测试;早期版本主要体现CPU计算性能,但是现在的计算机有很多是用在服务器、云计算领域,更关注数据传输性能,因此新版本也增加了CPU与内存、外围设备(简称外设)交换数据的测试因素。
除了SPEC CPU之外,业界还推出了很多其他的测试工具。例如,专门用于访存性能的测试工具STREAM,用来测试CPU对内存的访问速度。这个工具运行时会对内存发起大量数据请求,如果数据在更短时间内传输完成,则代表访存性能更高。其他的测试工具还有针对嵌入式应用的EEMBC,该软件非常简单,数据量很小,很适合在低性能的CPU上测试。
性能测试工具的局限性
“完美的测试集”不存在
性能测试工具的名称虽然叫作SPEC CPU,但是本质上测试的是硬件和软件的联合性能。SPEC CPU本身是用高级语言编写的,需要经过编译器、操作系统的支持才能运行。现代计算机系统是硬件和软件联合工作,软件也是决定性能的重要因素。
性能测试工具的局限性具体如下。
第一个局限性是编译器对SPEC CPU分值的影响。在同样的CPU上,优化编译器是可以提升软件执行效率的。编译器是把高级语言源代码转换成CPU所能执行的二进制指令的软件。优秀的编译器能够使用更多的优化算法,生成更高效的二进制指令。例如Intel公司自己开发了编译器icc,效率能比开源的编译器gcc高50%以上。Intel公司提交到SPEC CPU网站上的数据都是使用icc编译的,SPEC CPU测试报告如图1.11所示。
图1.11 一份SPEC CPU测试报告,Compiler部分采用Intel公司的C/C++编译器
但是这里有一个矛盾,实际应用中使用更多的是gcc而不是icc,用icc编译应用程序的计算机SPEC CPU分值虽然高,但并不代表用gcc编译的应用软件性能就高。所以有人戏称icc只是为了提高跑分的目的而做的编译器,其结果反映的不是CPU性能而是编译器性能。
第二个局限性是测试工具所选的问题不代表所有应用场景的问题,SPEC CPU分值高并不代表CPU运行所有的应用程序都能有好的效果。SPEC CPU毕竟只包含几十个问题,而且主要是面向计算型应用。为了使SPEC CPU跑分高,完全可以在设计CPU时只注重提高计算性能,例如在CPU中多放置几个浮点计算单元,或者在一个芯片中放置更多的CPU核,同时运行,靠量取胜。
但是这样的CPU用在日常生活中是不合适的,像台式计算机和手机并不处理这么多数值计算应用。就像有的手机运行跑分软件分值非常高,但是运行日常使用的拍照、聊天等应用反而卡顿。
“完美的测试集”只能存在于想象中,用户在使用SPEC CPU时需要清楚地知晓这些局限性,以免被数据误导。
虽然SPEC CPU有诸多不足,但是它目前仍然是衡量计算机性能的最权威工具。无论是修改编译器,还是为了跑分高而在CPU中加入专门的设计,都有“骗测试集”之嫌,但是想把SPEC CPU分值提高到一流水平仍然是需要硬实力的。
不推荐的测试集:UnixBench
使用开源软件时一定要查清它的明显缺陷,避免被其误导
UnixBench是一款测试UNIX操作系统基本性能的开源工具。UnixBench也适合所有兼容UNIX的操作系统的性能测试,例如Linux、FreeBSD等。
UnixBench的主要测试项目有操作系统向应用程序提供的编程接口(系统调用)、程序创建、程序之间的通信、文件读写、图形测试(2D和3D)、数学运算、C语言函数库等。
如果用户在网上寻找操作系统性能测试工具,几乎都会搜索到UnixBench。但是,UnixBench不适合作为性能测试标准,因为这个工具有很大的缺陷。
UnixBench不能体现计算机的实际性能。UnixBench于1995年推出,更新缓慢,2012年之后项目基本停滞。作为计算机UNIX操作系统早期的测试程序,UnixBench测试项目较为老旧,对于当前计算机性能测试的参考意义有限,不适合作为评判指标。
这里仅列举两个UnixBench中问题最大的子项目。
● 在测试数学运算性能时使用Dhrystone和Whetstone程序。这两种测试不能代表现代高性能CPU的定点和浮点性能,因为程序执行模式过于简单,与实际应用的复杂程度差距大;测试集太小,对于内存的压力几乎没有,而实际应用与CPU、内存的性能都有综合的关系。基于这个原因,业界已经不再使用Dhrystone和Whetstone程序,而是转向更专业的SPEC CPU工具。
● 在测试图形性能时使用x11perf程序。这种测试使用的是一种老旧的UNIX图像显示机制(x11),而现在的计算机都使用显卡硬件加速机制显示图像,大多数情况下不使用x11的显示机制,所以x11perf分值和计算机的实际图像性能没有直接关系。
龙芯3A4000的UnixBench测试数据如图1.12所示。正如上面所分析的,UnixBench分值不能代表CPU、操作系统的性能。使用UnixBench测试出来的分值会有很大的误导性,真正有意义的测试工具还是SPEC CPU和STREAM。
图1.12 龙芯3A4000的UnixBench测试数据