转载-计算机组成原理--如何判定及提高计算机性能?

0. 前言

非科班出身,特此来补计算机基础知识。

本文为转载文章,原文地址:https://www.toutiao.com/i6723499967727534604/

本文引言:

  • 买电脑时,“原来的电脑性能跟不上啦”
  • 写程序时,“这个程序性能可以优化一下”

这虚无缥缈的“性能”到底指的是什么呢?

我们能不能给性能下一个明确的定义,然后来进行准确的比较呢?

在计算机组成原理乃至体系结构中,“性能”都是最重要的一个主题。

学习和研究计算机组成原理,就是在理解计算机是怎么运作的,以及为什么要这么运作。

“为什么”所要解决的事情,很多时候就是提升“性能”。

1 时间的倒数 - 性能

计算机的性能,其实和体力劳动很像,好比是我们要搬东西。

对于计算机的性能,我们需要有个标准来衡量。这个标准中主要有两个指标。

  • 响应时间(Response time)& 执行时间(Execution time)

让计算机“跑得更快”。我们执行一个程序,到底需要花多少时间。花的时间越少,自然性能就越好。

  • 吞吐率(Throughput)& 带宽(Bandwidth)

让计算机“搬得更多”。服务器使用的网络带宽,通常就是一个吞吐率性能指标.吞吐率是指我们在一定的时间范围内,到底能处理多少事情。这里的“事情”,在计算机里就是处理的数据或者执行的程序指令。

和搬东西对比,如果响应时间短,跑得快,我们可以来回多跑几趟搬几趟。

所以缩短程序的响应时间,一般来说都会提升吞吐率

除了缩短响应时间,我们还有别的方法吗?当然!

我们还可以多找几个人一起来搬,这就类似服务器都是多核的。

人多力量大,同时处理数据,在单位时间内就可以处理更多数据,吞吐率自然也就上去了。

提升吞吐率的办法有很多。大部分时候,我们只要多加一些机器,多堆一些硬件就好了。


但是响应时间的提升却没有那么容易,因为CPU的性能提升其实在10年前就处于“挤牙膏”的状态了,所以我们得慎重地来分析对待。

下面我们具体来看。

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

$$ 性能 = 1/响应时间 $$

响应时间越短,性能数值越高。

同样一个程序

  • 在Intel最新的CPU Coffee Lake上,只需要30s就能运行完成
  • 而在5年前CPU Sandy Bridge上,需要1min才能完成

那么我们自然可以算出来,Coffee Lake的性能是1/30,Sandy Bridge的性能是1/60,两个的性能比为2。于是,我们就可以说,Coffee Lake的性能是Sandy Bridge的2倍。

过去几年流行的手机跑分软件,就是把多个预设好的程序在手机上运行,然后根据运行需要的时间,算出一个分数来给出手机的性能评估。

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

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

2.1 时间的测不准原理

如果用你自己随便写的一个程序,来统计程序运行的时间,每一次统计结果不会完全一样。

为什么会不准呢?这里面有好几个原因。

2.1.1 统计时间方法

我们统计时间是用类似于“掐秒表”一样,记录 程序运行结束时间减去程序开始运行的时间。

这个时间也叫Wall Clock Time或者Elapsed Time

就是在运行程序期间,挂在墙上的钟走掉的时间。

但计算机可能同时运行着好多个程序,CPU实际上不停地在各个程序之间进行切换。

在这些走掉的时间里,很可能CPU切换去运行别的程序了。

而且,有些程序在运行的时候,可能要从网络、硬盘去读取数据,要等网络和硬盘把数据读出来,给到内存和CPU。

要想准确统计某程序的实际运行时间,进而比较程序之间的性能,须把这些额外时间除掉

那这件事怎么实现呢???

i> 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

一般情况下,如果user+sys比real大,甚至仅user比real大的情况出现,都是因为对应的程序被多个进程或者多个线程并行执行了,也很常见。

在多核或者多cpu的机器上运行,seq和wc命令会分配到两个cpu上,user和sys是两个cpu时间相加的,而real只是现实时钟里走过的时间,极端情况下user+sys可以到达real的两倍

虽然seq和wc这两个命令都是单线程运行的,但是这两个命令在多核cpu运行的情况下,会分别分配到两个不同的cpu,于是user和sys的时间都是两个cpu上运行的时间之和,就可能超过real的时间。

可以这样来快速验证,运行

time seq 100000000 | wc -l &

让这个命令多跑一会儿,并且在后台运行。

然后利用 top 命令看不同进程的cpu占用情况

你会在top的前几行里看到seq和wc的cpu占用都接近100,实际是各被分配到了一个不同的cpu执行。

2.1.2 不一定可直接比较出性能

即使我们已经拿到了CPU时间,我们也不一定可以直接“比较”出两个程序的性能差异

即使在同一台计算机上,CPU可能满载运行也可能降频运行,降频运行的时候自然花的时间会多一些。

除CPU外,时间这个性能指标还会受到主板、内存这些其他相关硬件的影响。

所以,我们需要对“时间”这个概念进行拆解。

2.2 CPU时间拆解

先给出总公式:

$$ CPU执行时间=CPU时钟周期数×每个时钟周期的时间 $$

2.2.1 时钟周期时间

你在买电脑的时候,一定关注过CPU的主频

如:

这里的2.8GHz就是电脑的主频(Frequency/Clock Rate)。

这个2.8GHz,我们可以先简单地理解为,CPU在1秒时间内,可以执行的简单指令的数量是2.8G条。

更准确点,这个2.8GHz就代表,我们CPU的一个“钟表”能够识别出来的最小的时间间隔

时钟周期时间就是指CPU所能识别出来的最小时间间隔。

就像我们挂在墙上的挂钟,都是一秒一秒地走,所以通过墙上的挂钟能够识别出来的最小时间单位就是秒。

而在CPU内部,有一个叫晶体振荡器(Oscillator Crystal)的东西,简称为晶振。

把晶振当成CPU内部的电子表来使用。

晶振带来的每一次“滴答”,就是时钟周期时间。

在我这个2.8GHz的CPU上,这个时钟周期时间,就是1/2.8G。

我们的CPU,是按照这个“时钟”提示的时间来进行自己的操作。

主频越高,意味着这个表走得越快,我们的CPU也就走得越快。

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

  • 回顾之前的CPU执行时间的公式程序:

$$ CPU执行时间=CPU时钟周期数×每个时钟周期的时间 $$

我们当然是想CPU执行时间越短越好,所以最简单的提升性能方案,自然是缩短时钟周期时间,也就是提升主频。

换句话说,就是换一块好一点的CPU。

2.2.2 CPU时钟周期数

主频,这个是我们这些底层的研发人员控制不了的,所以我们就把目光挪到了乘法的另一个因子——CPU时钟周期数上

CPU时钟周期数量指的是运行单个程序的所有指令总共所需要的时钟周期数量。

如果能够减少程序需要的CPU时钟周期数量,一样能够提升程序性能。对于CPU时钟周期数,我们可以再做一个分解,把它变成

$$ CPU时钟周期数 = 程序中的总指令数×每条指令的平均时钟周期数(Cycles Per Instruction,简称CPI) $$

不同的指令需要的Cycles是不同的,如:

  • 加法和乘法都对应着一条CPU指令
  • 但是乘法需要的Cycles就比加法要多,自然也就慢。

2.2.3 最终结果

在这样拆分了之后,我们的程序的CPU执行时间就可以变成这样三个部分的乘积。

$$ 程序的CPU执行时间=程序总指令数 × CPI × 时钟周期时间 $$

因此,要解决性能问题,就是要优化这三者

  • 指令数,代表执行我们的程序到底需要多少条指令、用哪些指令,这个很多时候就把挑战交给了编译器。同样的代码,编译成计算机指令时候,就有各种不同的表示方式。
  • 每条指令的平均时钟周期数CPI。一条指令到底需要多少CPU Cycle。在后面讲解CPU结构的时候,我们会看到,现代的CPU通过流水线技术(Pipeline),让一条指令需要的CPU Cycle尽可能地少。因此,对于CPI的优化,也是计算机组成和体系结构中的重要一环。
  • 时钟周期时间,就是计算机主频,取决于硬件。最早的80386主频只有33MHz,现在手头的笔记本电脑就有2.8GHz,在主频层面,就提升了将近100倍。

2.2.4 打个比方

把自己想象成一个CPU,坐在那里写程序。

  • 计算机主频就好像是你的打字速度,打字越快,你自然可以多写一点程序。
  • CPI相当于你在写程序的时候,熟悉各种快捷键,越是打同样的内容,需要敲击键盘的次数就越少。
  • 指令数相当于你的程序设计得够合理,同样的程序要写的代码行数就少。

如果三者皆能实现,你自然可以很快地写出一个优秀的程序,“性能”从外面来看就是好的。

2.2.5 额外知识补充

1.时钟周期、机器周期、指令周期的区别?

一个指令周期包含多个机器周期,一个机器周期又包含多个时钟周期。

3 总结

学完本文,对“性能”这个名词,你应该有了更清晰的认识。

主要对于“响应时间”这个性能指标进行抽丝剥茧,拆解成了计算机时钟周期、CPI以及指令数这三个独立的指标的乘积,并且为指明了优化计算机性能的三条康庄大道。

也就是,提升计算机主频,优化CPU设计使得在单个时钟周期内能够执行更多指令,以及通过编译器来减少需要的指令数。

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

参考

Last modification:August 20th, 2019 at 11:20 am
如果觉得我的文章对你有用,请随意赞赏

Leave a Comment