深入计算机组成原理(三)通过你的CPU主频,我们来谈谈"性能"究竟是什么?

“性能”这个词,不管是在日常生活还是写程序的时候,都经常被提到。比方说,买新电脑的时候,我们会说“原来的电脑性能跟不上了”;写程序的时候,我们会说,“这个程序性能需要优化一下”。那么,你有没有想过,我们常常挂在嘴边的“性能”到底是指的什么呢?我们能不能给性能下一个明确的定义,然后来进行准确的比较呢?

在计算机组成原理乃至体系结构中,“性能”都是一个最重要的一个主题。我在前面说过,学习和研究计算机组成原理,就是在理解计算机是怎么运作的,以及为什么要这么运作。“为什么”所要解决的事情,很多时候都是提升”性能“。

什么是性能?时间的倒数

计算机的性能,其实和我们干体力劳动很像,好比是我们要搬东西。对于计算机的性能,我们需要有个标准来衡量。这个标准中主要有两个指标。

第一个是响应时间(Response time)或者叫执行时间(Execution time)。想要提升响应时间这个性能指标,你可以理解为让计算机”跑的更快“。

深入计算机组成原理(三)通过你的CPU主频,我们来谈谈

第二个是吞吐率(Throughput)或者带宽(Bandwidth),想要提升这个指标,你可以理解为让计算机”搬的更多“。

深入计算机组成原理(三)通过你的CPU主频,我们来谈谈

所以说,响应时间指的就是,我们执行一个程序,到底需要花多少时间。花的时间越少,自然性能就越好。

而吞吐率是指我们在一定的时间范围内,到底能处理多少事情。这里的”事情“,在计算机里就是处理的数据或者执行的程序指令。

和搬东西来做对比,如果我们的响应时间短,跑得快,我们就可以来回多跑几趟多搬几趟。所以说,缩短程序的响应时间,一般来说都会提升吞吐率。

除了缩短响应时间,我们还有其他方法吗?当然有,比如说,我们还可以多找几个人一起搬,这就类似现代的服务器都是8核、16核的。人多力量大,同时处理数据,在单位时间内就可以处理更多数据了,吞吐率自然就上去了。

提升吞吐率的办法有很多。大部分时候,我们只需要多加机器,多堆一些硬件就好了。但是响应时间的提升却没有那么容易,因为CPU的性能提升其实在10年前就处于”挤牙膏“的状态了,所以我们得慎重地分析对待。下面我们具体来看。

我们一般把性能,定义成响应时间的倒数,也就是:

										性能 = 1 / 响应时间

这样一来,响应时间越短,性能的数值就越大。同样一个程序,在Intel最新的CPU Coffee Lake上,只需要30s就能运行完成,而在5年前的CPU Sandy Bridge上,需要1min才能完成。那么我们自然可以算出来,Coffee的性能是1/30,Sandy Bridge的性能是1/60,两个的性能比为2.于是,我们就可以说,Coffee Lake的性能是Sandy Bridge的2倍。

过去几年流行的手机跑分软件,就是把多个预设好的程序在手机上运行,然后根据运行需要的时间,算出一个分数来给手机的性能评估。而在业界,各大CPU和服务器厂商组织了一个叫做SPEC的第三方机构,专门用来指定各种”跑分“的规则。

深入计算机组成原理(三)通过你的CPU主频,我们来谈谈

SPEC提供的CPU基准测试程序,就好像CPU届的”高考“,通过数十个不同的计算程序,对于CPU的性能给出一个最终评分。这些程序丰富多彩,有编译器、解释器、视频压缩、人工智能国际象棋等等,涵盖了方方面面的应用场景。感兴趣可点击这个链接。

计算机的计时单位:CPU时钟

虽然时间是一个很自然的用来衡量性能的指标,但是用时间来衡量时,有两个问题。

第一个就是时间不“准”。如果你用自己随便写的一个程序,来统计程序运行的时间,每一次统计结果不会完成一样,有可能这一次花了45ms,下一次变成了53ms。

为什么会不准呢?这里面有好几个原因。首先,我们统计时间是用类似于”掐秒表“一样,记录程序运行结束的时间减去程序开始运行的时间。这个时间也叫 Wall Clock Time 或者 Elapsed Time,就是在运行程序期间,挂在墙上的钟走掉的时间。

但是,计算机可能同时运行着好多个程序,CPU实际上不停的在各个程序之间切换。在这些走掉的时间里面,很可能CPU切换去执行别的程序了。而且,有些程序在运行的时候,可能要从网络、硬盘去读取数据,要等网络和硬盘把数据读出来,给到内存和CPU。所以说,要想准确统计某个程序的运行时间,进而去比较两个程序的实际性能,我们得把这些时间给刨除掉

那这件事怎么实现呢?Linux系统下有一个叫time的命令,可以帮我们统计出来,同样的Wall Clock Time下,程序实际在CPU上到底花了多少时间。

我们简单运行一下time命令。它会返回三个值,第一个是real time,也就是我们说的Wall Clock Time,也就是运行程序整个过程中流逝掉的时间;第二个是user time,也就是CPU在运行你的程序,在用户态运行指令的时间;第三个是 sys time,是CPU在运行你的程序,在操作系统内核里运行指令的时间。而程序实际花费的CPU执行时间(CPU Time),就是user time 加上 sys time

time seq 1000000 | wc -l
1000000


real  0m0.101s
user  0m0.031s
sys   0m0.016s

在我给的这个例子里,你可以看到,实际上程序用了0.101s,但是CPU time只有0.031+0.016 = 0.047s。运行程序的时间里,只有不到一半的是实际花在这个程序上的。

深入计算机组成原理(三)通过你的CPU主频,我们来谈谈

其次,即使我们已经拿到了CPU时间,我们也不一定可以直接”比较“出两个程序的性能差异。即使在同一台计算机上,CPU可能满载运行也可能降频运行,降频运行的时候自然花的时间会多一些。

除了CPU之外,时间这个性能指标还会受到主板、内存这些其他相关硬件的影响。所以,我们需要对”时间“这个我们可以感知的指标进行拆解,把程序的CPU执行时间变成CPU时钟周期数(CPU Cycles)和时钟周期时间(Clock Cycle)的乘积。

							程序的CPU执行时间 = CPU时钟周期数 x 时钟周期时间

我们先来理解一下什么是时钟周期时间。你在买电脑的时候,一定关注过CPU的主频。假如一个CPU的主频是2.8GHz,我们可以先粗浅的认为,CPU在1秒时间内,可以执行的简单指令的数量是2.8G条。

如果想要更准确一点描述,这个2.8GHz就代表,我们CPU的一个”钟表“能够识别出来的最小的时间间隔。就像我们挂在墙上的挂钟,都是”滴答滴答“一秒一秒的走,所以通过墙上的挂钟能够识别出来的最小时间单位就是秒。

而在CPU内部,和我们品是戴的电子石英表类似,有一个叫晶体振荡器的东西,简称为晶振。我们把晶振当成CPU内部的电子表来使用。晶振带来的每一次滴答,就是时钟周期时间。

如果你自己组装过台式机的花,可能听说过”超频“这个概念,这说的其实就是相当于把买回来的CPU内部的钟给调快了,于是CPU的计算跟着这个时钟的节奏,也就自然变快了。当然这个快不是没有代价的,CPU跑的越快,散热的压力也就越大。就和人一样,超过生理极限,CPU就会崩溃了。

我们回到上面程序CPU执行时间的公式

							程序的CPU执行时间 = CPU时钟周期数 x 时钟周期时间

最简单的提升性能方案,自然缩短时钟周期时间,也就是提升主频。换句话说,就是换一块好一点的CPU。不过,这个是我们这些软件工程师控制不了的事情。所以我们就把目光挪到了乘法的另一个因子——CPU时钟周期数上。如果能够减少程序所需要的CPU时钟周期数,一样能够提升程序性能。

对于CPU时钟周期数,我们可以再做一个分解,把它变成”指令数 x 每条指令的平均时钟周期数(Cycles Per Instruction,简称CPI)“。不同的指令需要的Cycles是不同的,加法和乘法都对应着一条CPU指令,但是乘法需要的Cycles就比加法要多,自然也就慢。在这样拆分了之后,我们的程序的CPU执行时间就可以变成这三个部分的乘积。

							程序的CPU执行时间 = 指令数 x CPI x ClockCycleTime

因此,如果我们想要解决性能问题,其实就是要优化这三者。

1.时钟周期时间,就是计算机主频,这个取决于计算机硬件。我们所熟知的摩尔定律就一直在不停的提高我们计算机的主频。
2.每条指令的平均时钟周期数CPI,就是一条支流到底需要多少CPU Cycle。在后面讲解CPU结构的时候,我们会看到,现代的CPU通过流水线技术(Pipeline),让一条指令需要的CPU Cycle尽可能的少。因此,对于CPI的优化,也是计算机组成和体系结构钟的重要一环。
3.指令数,代表执行我们的程序到底需要多少条指令、用哪些指令。这个很多时候就把挑战交给了编译器,同样的代码,编译成计算机指令的时候,就有各种不同的表示方式。

我们可以把自己想象成一个CPU,坐在那里写程序。计算机主频就好像是你的打字速度,打字越快,你自然可以多写一点程序。CPI相当于你在写程序的时候,熟悉各种快捷键,越是打同样的内容,需要敲击键盘的次数就越少。指令数相当于你的程序设计的够合理,同样的程序要写的代码量就少。如果三者皆能实现,你自然就能很快写出一个优秀的程序,你的”性能“从外面看就是好的。

总结延伸

好了,学完这一讲,对“性能”这个名词,你应该有了更清晰的认识。我主要对于“响应时间”这个性能指标进行抽丝剥茧,拆解成了计算机时钟周期、CPI 以及指令数这三个独立的指标的乘积,并且为你指明了优化计算机性能的三条康庄大道。也就是,提升计算机主频,优化 CPU 设计使得在单个时钟周期内能够执行更多指令,以及通过编译器来减少需要的指令数。

在后面的几讲里面,我会为你讲解,具体怎么在电路硬件、CPU 设计,乃至指令设计层面,提升计算机的性能。

思考

每次有新手机发布的时候,总会有一些对于手机的跑分结果的议论。乃至于有”作弊“跑分或者”针对跑分优化“的说法。我们能针对跑分作弊吗?怎么做到呢?作弊出来的分数对真实的手机性能还有参考意义吗?

你可能感兴趣的:(计算机组成原理,计算机组成原理)