2、计算机性能

1、性能

起因

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

学习和研究计算机组成原理,就是在理解计算机是怎么运作的,以及为什么要这么运作。“为什么”所要解决的事情,很多时候就是提升“性能”

什么是性能?

计算机的性能和人类体力劳动很像,好比我们搬东西。对于计算机性能,我们的衡量标准主要有两个指标:

  • 响应时间:响应时间也可以叫执行时间,可以理解为让计算机“跑的更快”
  • 吞吐率:吞吐率或者带宽,可以理解为让计算机“搬得更多”

响应时间指的是,执行一个程序,到底需要花多少时间。花的时间越少,自然性能就越好。
吞吐率指我们在一定的时间范围内,到底能处理多少事情。这里的“事情”,在计算机里就是处理的数据或者执行的程序指令

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

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

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

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

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

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

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

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

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

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

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

要实现这件事,可以使用time命令(linux系统下)

[root@xad wwwroot]# time curl https://www.baidu.com
...
real	0m0.268s  # 运行程序整个过程中流逝掉的时间
user	0m0.062s  # cpu运行你的程序,在用户态运行指令的时间
sys		0m0.068s  # cpu运行你的程序,在操作系统内核运行指令的时间

程序实际花费的CPU执行时间 = user time + sys time

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

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

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

什么是时钟周期时间

假设某一台电脑的CPU为:Intel Core-i7-7700HQ 2.8GHz,这里的2.80GHz就是电脑的主频(Frequency/Clock Rate)。这个2.80GHz,我们可以粗浅的认为,CPU在1秒时间内,可以执行的简单指令的数量是2.8G条。

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

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

	CPU主频是一个频率(frequency),频率的单位叫做赫兹(Hz)。意思是一秒内这个事情可以发生多少次。主频2.8GHz就代表一秒内晶振振动了2.8G次,这里的G其实就是10亿次,也就是28亿次。那么我们的时钟周期时间就是1/28亿秒。

在这个2.8GHz的CPU上,这个时钟周期时间,就是1/2.8G。我们的CPU,是按照这个“时钟”提示的时间来进行自己的操作。主频越高,意味着这个表走的越快,我们的CPU也被逼着走的越快

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

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

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

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

CPU时钟周期数

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

	程序的CPU执行时间 = 指令数 * CPI * Clock Cycle Time

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

  1. 时钟周期时间,就是计算机主频,这个取决于计算机硬件。
  2. 每条指令的平均时钟周期数CPI,就是一条指令到底需要多少CPU Cycle。
  3. 指令数,代表执行我们的程序到底需要多少条指令,用哪些指令。这个很多时候就把挑战交给了编译器。同样的代码,编译成计算机指令的时候,就有各种不同的表示方式

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值