目录
1 概述
1.1 计算机体系结构体中的8个伟大思想
1.2 计算机层次结构
1.2.1 概述
1.2.2 指令集体系结构
1.3 实例:从程序到电子信号
1.3.1 从高级语言到汇编语言
1.3.2 从汇编语言到机器语言
1.3.3 生成可执行文件并执行
1.3.4 计算机基本执行结构
1.3.4.1 概述
1.3.4.2 取指过程
1.3.4.3 执行过程
2 存储程序思想和冯.诺依曼体系结构
2.1 存储程序思想
2.2 冯.诺依曼体系结构
3 理解计算机性能
3.1 计算机性能的定义
3.2 计算机性能的度量
3.2.1 以时间为度量标准
3.2.2 CPU执行时间
3.3 CPU性能及其度量因素
3.3.1 系统性能和CPU性能
3.3.2 时钟周期与时钟频率
3.3.3 CPU性能公式
3.4 指令的性能
3.5 经典的CPU性能公式
3.6 SPEC CPU基准测试程序
3.7 Amdahl定律
4 功耗墙
4.1 动态功耗
4.2 静态功耗
5 从单处理器向多处理器转变
1 概述
1.1 计算机体系结构体中的8个伟大思想
1. 面向摩尔定律设计
由于计算机设计通常需要几年时间,因此根据摩尔定律(Moore's Law),项目结束时芯片的集成度较之项目开始时,很容易翻一番甚至翻两番。所以计算机体系结构设计师应当预测设计完成时的工艺和技术水平,而不是设计开始时的工艺
2. 使用抽象简化设计
提高硬件和软件开发效率的主要技术之一是使用抽象(abstraction)来表征不同级别的设计,即在低层将细节隐藏起来,呈现给高层的只是一个简化的模型
3. 加速大概率事件
① 加速大概率事件(common case fast)远比优化小概率事件更能提高性能。大概率事件通常比小概率事件简单,因而更易于对其进行优化以提高性能
② 加速大概率事件,意味着设计者需要知道哪些事件是经常发生的。以深度学习的计算过程为例,99%的计算是向量和矩阵计算,所以通过使用GPU代替CPU可以大幅提升深度学习模型的训练过程
4. 通过并行提高性能
从计算机诞生开始,计算机设计者就通过并行执行操作来提高性能
5. 通过流水线提高性能
流水线(pipelining)就是计算机体系结构中非常普遍的一种并行技术
6. 通过预测提高性能
① 假设预测错误后恢复的代价不大,并且预测的准确率相对较高,那么通过猜测的方式提前开始工作,要比等到确定知道能执行时才启动效率更高
② 预测也体现了加速大概率事件的思想
7. 存储器层次结构
① 存储器的速度影响性能,存储器的容量限制解题规模
② 程序员希望存储器速度更快、容量更大、价格更便宜,计算机设计师则通过存储器层次结构(hierarchy of memory)来缓解这些相互矛盾的需求
③ 在存储器层次结构中,位于顶层的存储器速度最快、容量最小、价格最贵;反之,位于底层的存储器速度最慢、容量最大、价格最便宜
8. 通过冗余提高可靠性
任何一个物理器件都有可能失效,因此可以通过增加冗余器件的方式提高系统的可靠性(dependable),冗余器件可以替代失效器件并帮助检测错误
1.2 计算机层次结构
1.2.1 概述
1. 简化的计算机软硬件层次结构如下图所示,最外层是应用软件,中心是硬件,各种系统软件(systems software)位于两者之间
2. 系统软件是指提供公共服务的程序,其中对于现代计算机系统最为重要的是如下三种,
① 操作系统(operating system)
用户程序和硬件之间的接口,为用户提供各种服务和管理功能
② 编译器(compiler)
将用高级语言(e.g. C、C++、Java)编写的程序翻译成汇编语言
③ 汇编器(assembler)
将汇编语言(计算机指令系统的符号化表示)翻译成计算机硬件能够识别的二进制指令
说明1:从高级语言到二进制指令的翻译过程如下图所示,
说明2:一个应用程序可以实现复杂的功能,但是计算机硬件只能执行极为简单的低级指令。因此从复杂的应用程序到简单的指令,需要经过几个软件层次来将高层的操作逐步翻译成简单的计算机指令。其中的每个层次都为上一层隐藏了自己的技术细节,这就是抽象思想的体现
1.2.2 指令集体系结构
1. 计算机层次结构中最重要的抽象,就是硬件和底层软件之间的接口,该抽象层被称为指令集体系结构(Instruction Set Architecture,ISA),或简称体系结构
2. 指令集体系结构是对硬件层次的抽象,包含了正确编写机器语言程序所需的全部信息,如指令集、寄存器、访存和IO操作等
3. 计算机设计者将计算机体系结构和计算机体系结构的实现(implementation)分开考虑,所谓计算机体系结构体的实现是指遵循体系结构抽象的硬件实现
只要遵循相同的指令集体系结构,虽然不同的硬件实现在成本和性能上可能各不相同,但是仍然可以支持相同软件的执行
说明:通常通过操作系统将IO操作、内存分配和其他底层系统功能的细节封装起来,应用程序员无需关心这些细节,提供给应用程序员的基本指令集和操作系统接口合称为应用程序二进制接口(Application Binary Interface,ABI)
一个提供给应用程序的ABI实例,就是操作系统的系统调用规则,其中会规定触发系统调用的指令、传递系统调用号所使用的寄存器以及返回系统调用结果所使用的寄存器
1.3 实例:从程序到电子信号
1.3.1 从高级语言到汇编语言
以计算整数18和40的和为例,我们使用C语言实现该功能,并且通过编译器将其翻译成汇编语言
1.3.2 从汇编语言到机器语言
编译后生成的汇编语言再经过汇编器,就可以翻译成计算机硬件能够执行的机器指令
说明:在示例指令集体系结构体中,B8和A3都是MOV指令的操作码,但是他们处理的操作数不同
① B8是向寄存器存储数据
② A3是向内存存储数据
1.3.3 生成可执行文件并执行
1. 源程序在经过编译和汇编之后,还需要和其他目标文件链接,才能生成可执行文件
2. 生成的可执行文件以文件形式存储在外存中,当需要运行该文件时,操作系统将其加载到内存中并逐条指令执行
1.3.4 计算机基本执行结构
1.3.4.1 概述
1. 计算机执行程序的过程,就是逐条执行加载到内存中的二进制机器指令流的过程
2. 一条指令的执行过程可以简单地分为两个操作阶段,
① 取指阶段:CPU从内存中读取指令,程序计数器保存要被取出的下一条指令的地址。除非遇到跳转指令等情况,程序计数器一般在每次取指后加上一个增量(当前指令的字节数)
② 执行阶段:对取出的指令先译码,解释指令的功能,然后执行译码好的指令,这期间可能会读写内存或端口来获取操作数或存放计算结果
1.3.4.2 取指过程
1. 假设将可执行程序加载在内存00H地址处,并且将程序计数器PC赋值为00H,则CPU将从程序的第一条指令开始执行
2. 生成取值地址
① 将PC寄存器的值00H送入地址寄存器AR,然后自增PC寄存器,步长为指令长度2B
② 地址寄存器AR的值00H通过总线控制逻辑被放置到地址总线上,经过地址译码选中从00H开始的2个连续内存单元
3. 读取指令
CPU的控制逻辑通过控制总线发出读控制信号,将选中的00H和01H这2个内存单元中的内容通过数据总线读取到指令寄存器IR中
1.3.4.3 执行过程
1. 将IR中的第一个字节操作码B8H送到指令译码ID和控制逻辑单元,对其进行译码后,判断出是要将IR寄存器中的操作数12H送到累加寄存器A中
2. 总线控制逻辑先将操作数送到数据寄存器DR中,然后通过内部数据总线将操作数送到累加寄存器A中
2 存储程序思想和冯.诺依曼体系结构
2.1 存储程序思想
存储程序思想就是将事先设计好,用以描述计算机解题过程的程序如同数据一样,采用二进制形式存储在机器中。计算机在工作时,自动地从机器中逐条取出指令加以执行
说明1:如果计算机不存储程序会怎样?
① 计算器是一种典型的不存储程序的计算机,假设同样是计算整数18和40的和,使用计算器时的数据和指令都需要操作者按键输入。也就是说,操作命令存储在人脑中,而非机器中,此时就无法由机器自动进行运算
② 还有一种不存储程序的计算机,就是通过开关和连接线来设置程序指令的计算机(e.g. 最早的电子计算机ENIAC)。此时如果要切换程序,则需要改变开关和连接线,操作麻烦且低效
说明2:计算机如何区分指令和数据?
① 计算机将通过程序计数器PC从内存中寻址得到的内容作为指令,其他方式寻址得到的内容作为数据
② 如果PC寄存器寻址的内存中存储的不是有效指令,计算机依然会将其作为指令进行译码和执行,这将导致错误
2.2 冯.诺依曼体系结构
冯.诺依曼体系结构计算机由如下5个部件组成,任何计算机中的任何部件都归属于这5个部件之一,
1. 输入设备
① 将程序和数据写入存储器
② 输入过程中会将信息转换为计算机能识别的形式
2. 输出设备
① 从存储器中读出数据
② 输出过程中会将数据转换为用户便于使用的形式
3. 存储器
存放程序、数据和程序运行的中间结果
4. 运算器(也称作数据通路,datapath)
负责完成算术和逻辑运算
5. 控制器
根据程序指令产生控制信号,指导运算器、存储器、输入设备和输出设备按照指令的要求协同工作
说明:处理器的概念与构成
① 一般将冯.诺依曼体系结构中的运算器和控制器合称为处理器,即CPU
② 运算器的核心由算术逻辑单元ALU(Arithmetic Logic Unit)和寄存器堆(Register File)组成,其中,
- ALU用来执行算术逻辑运算
- 寄存器堆用来存储临时的数据或控制信息(e.g. PC、IR)
3 理解计算机性能
3.1 计算机性能的定义
计算机有如下2种基本的性能指标,
1. 响应时间(response time)
① 响应时间是指计算机完成单个任务所需的总时间,包括磁盘访问、内存访问、IO操作、操作系统开销以及CPU执行时间等
② 响应时间又称作执行时间(execution time)
2. 吞吐率(throughput)
① 吞吐率是指计算机在单位时间内完成的任务总量
② 吞吐率又称作带宽(bandwidth)
说明1:不同应用场景的用户,会关注不同的性能指标
① 个人计算机用户更关注降低计算机的响应时间
② 数据中心管理员更关注提升计算机的吞吐率
对于上述不同的场景,需要使用不同的性能指标和基准测试程序
说明2:分析下列措施对响应时间和吞吐率的影响
① 将计算机中的处理器更换为更高速的型号
- 因为处理器速度更快,所以可以减少响应时间
- 减少响应时间的措施一般都可以增加吞吐率
② 增加多个处理器分别处理独立的任务
- 因为处理器本身没有变化,所以单个任务的执行时间不会变化,直观地看不会减少计算机的响应时间
- 因为处理器个数增加,也就是可以同时执行的任务增加,所以可以提升计算机的吞吐率
- 当需要处理的任务数量达到吞吐率上限时,系统会要求请求的任务排队等待。在这种情况下,因为吞吐率的增加使得排队等待时间缩短,所以单个任务的响应时间也相应减少
3.2 计算机性能的度量
3.2.1 以时间为度量标准
1. 在当前讨论计算机性能时,主要考虑响应时间。为了使得性能最大化,就需要任务的响应时间或执行时间最小。对于某个计算机X,性能可表示为响应时间或执行时间的倒数
2. 如果说计算机X比计算机Y性能更换,则有如下关系,因此可以使用时间来度量计算机性能
3. 在定量比较计算机性能时,如果说计算机X的性能是计算机Y的n倍,则有如下关系,也就是计算机Y的执行时间是计算机X的n倍
说明:相对性能计算示例
如果计算机A运行一个程序需要10秒,计算机B运行同样的程序需要15秒,那么计算机A的性能是计算机B的1.5倍
3.2.2 CPU执行时间
在使用时间来度量计算机性能的情况下,时间也有不同的定义方法
1. 墙上时间
① 对时间最直接的定义就是墙上时间,也就是响应时间或消逝时间
② 这些术语均表示完成一项任务所需的总时间,包括磁盘访问、内存访问、IO操作和操作系统开销等一切时间
2. CPU执行时间
① CPU执行时间(CPU execution time)或简称CPU时间,表示CPU完成一项任务花费的计算时间。响应时间和CPU执行时间有如下关系,
响应时间 = CPU执行时间 + 其他时间 |
② CPU执行时间又可以进一步区分为,
- 用户CPU时间(user CPU time):用来运行用户程序所花费的CPU时间
- 系统CPU时间(system CPU time):操作系统为运行用户程序所花费的CPU时间
3.3 CPU性能及其度量因素
3.3.1 系统性能和CPU性能
1. 系统性能(system performance)表示空载系统的响应时间,所谓空载系统是指没有运行用户程序时的系统,此时的响应时间主要是操作系统等系统软件的开销
2. CPU性能(CPU performance)表示用户CPU时间
说明:本章主要关注的是CPU性能,也就是CPU真正用于执行用户程序的时间
3.3.2 时钟周期与时钟频率
1. 评价计算机性能的最重要指标是用户CPU时间,如果计算机中存在一个基本时间单元,则可以将用户CPU时间拆分为如下形式,从而为提升CPU性能提供依据
用户CPU时间 = 执行用户程序需要的计算机基本时间单元数量 * 基本时间单元 |
2. 在计算机中,这种基本时间单元就是时钟周期
① 时钟周期(Clock Cycle)
所有计算机都有一个固定频率的硬件时钟,用于决定各种硬件事件发生和执行的时间和顺序,该硬件时钟所产生的离散时间间隔称为时钟周期
② 时钟频率(Clock Rate)
时钟频率是时钟周期的倒数
说明:时钟周期与时钟频率示例
假设计算机的时钟周期为250ps(1ps = 10^-12s),则对应的时钟频率为4GH
时钟频率 = 1 / 时钟周期 = 1 / 250ps = 4GHz |
3.3.3 CPU性能公式
1. 在引入时钟周期和时钟频率的概念之后,CPU性能可以表示为,
2. 根据上述CPU性能公式,可以从如下两方面改进性能,
① 减少程序的时钟周期数
② 减少时钟周期长度,即提高时钟频率
说明1:性能改进中的权衡
在实际的性能改进方案中,有些技术在减少程序时钟周期数的同时会增加时钟周期长度,或者减少时钟周期长度的同时会增加程序时钟周期数,因此设计者需要在二者之间进行权衡
说明2:性能改进权衡示例
假设某程序在时钟频率为2GHz的计算机A上运行需要10秒,现在需要设计一台计算机B,希望将运行时间缩短为6秒。设计师有办法提高时钟频率,但是会导致计算机B运行该程序所需的时钟周期数增加到计算机A的1.2倍,那么计算机B的时钟频率需要提高到多少?
① 首先计算程序在计算机A上的时钟周期数
② 计算机B需要在时钟周期数增加1.2倍的情况下将运行时间缩短为6秒,则时钟频率需要提高到4GHz
③ 从上述示例可见,计算机B相较于计算机A虽然性能只提升了1.67倍,但是需要频率提升2倍
3.4 指令的性能
在上节的CPU性能公式中,程序的CPU时钟周期数还可以进一步拆分,以便更精确地度量。而拆分的方式就是将程序细化到指令层面,即有如下关系,
说明1:每条指令的平均时钟周期数
执行不同指令所需的时钟周期数是不同的,因此引入CPI(Clock cycles Per Instruction,每条指令的平均时钟周期数)的概念进行描述
说明2:指令性能公式使用示例
假设有相同指令集的两种不同实现方式,计算机A的时钟周期为250ps,对某程序的CPI为2.0;计算机B的时钟周期为500ps,对同样程序的CPI为1.2。对于该程序,哪台计算机的性能更好
① 由于两台计算机的指令集相同,因此对于相同程序的指令数相同,此处用I表示
② 每台计算机的CPU时钟周期数如下,
③ 每台计算机的CPU时间如下,
④ 可见计算机A的性能更好,且为计算机B的1.2倍
⑤ 从该示例可见,在优化指令性能时也需要权衡,有些技术在减小CPI的同时会增加时钟周期长度
3.5 经典的CPU性能公式
在引入CPU性能和指令性能的概念之后,就可以得到经典的CPU性能公式,
说明1:经典的CPU性能公式将CPU性能分解为三个关键要素,我们只要知道某些实现或设计对这三个参数的影响,就可以对不同方案进行比较和评估。算法、编程语言、编译器和体系结构对经典CPU性能公式中各因素的影响如下,
说明2:性能要素的测量
各性能要素的测量单位如下,需要注意的是,时间是唯一能够被完全可靠测量的性能指标
说明3:性能评价与要素优化中的权衡
① 经典CPU性能公式中的三个要素之间是相互关联的,在评价性能时需要综合考虑,只用一种要素去评价性能是不合理的
② 在对某个要素进行优化时,可能导致其他要素的劣化,从而抵消优化的效果
- 改进ISA以减少指令数可能会使时钟周期变长
- CPI的减少可能会增加时钟周期的长度
- 缩短时钟周期可能会增加指令数
说明4:时钟周期长度传统上是固定的,但是为了节省功耗或临时提升性能,当前的处理器可以动态调整时钟频率,因此在经典的CPU性能公式中需要使用平均时钟频率
3.6 SPEC CPU基准测试程序
1. 用户每日使用的程序是用于评价计算机性能的最佳选择,但是大多数用户不会这么做,而是使用一组专门用于测量性能的基准测试程序(benchmark)
2. SPEC(System Performance Evaluation Cooperative)是由许多计算机销售商共同赞助并支持的合作组织,目的是为现代计算机系统建立基准测试程序集(包括整数基准程序和浮点基准程序),下图为SPEC整数基准测试程序及其在Intel Core i7上的执行时间
说明1:为什么需要通过一组测试程序来评价计算机性能?
① 原因还是要回到经典CPU性能公式,因为CPI随着指令混合比(instruction mix)变化,所以即使时钟频率相同,也需要综合比较指令数和CPI,而一组测试程序集可以综合反应不同场景下的(指令数 * CPI)
② 所谓指令混合比,是指在一个或多个程序中,指令的动态使用频率,即各类指令所占的比例
③ 下面就给出一个综合考虑(指令数 * CPI)的示例,假设硬件设计者给出的各类指令CPI如下,
对于某行高级语言语句,编译器设计者正在考虑如下指令数量的两个代码序列,
可见代码序列1和代码序列2的指令数、时钟周期数和CPI如下,可见代码序列2虽然多执行一条指令,但执行的更快
说明2:使用三个性能要素的子集去度量性能是不合理的
① 首先,单独使用指令数、CPI或时钟频率去度量性能显然是不可行的;但是另一种常见的错误是只使用三个要素中的某两个去度量性能,虽然在某些条件下这样做可能是正确的,但是这种方法很容易被误用。实际上,几乎所有取代用时间去度量性能的方法都会导致歪曲的结果或错误的解释
② 例如MIPS(Million Instructions Per Second,每秒百万条指令)就是一种取代时间以度量性能的方法,对于一个给定的程序,MIPS计算公式如下,可见MIPS是指令执行的速率
③ 之所以说MIPS指标会造成误解,是因为我们将经典CPU性能公式代入其中,可见MIPS的值与CPI相关,而CPI的值又与不同程序的指令混合比相关。因此,即使在同一台计算机上,不同的程序也会有不同的MIPS值,也就无法稳定度量计算机性能
3.7 Amdahl定律
1. 计算机一个方面的改进对总体性能提升的影响,根据Amdahl定律计算式如下,
2. Amdahl定律表明某种改进可能带来的性能提升,受限于被改进部分被使用的次数,该规则是收益递减定律的量化版本
说明:Amdahl定律使用示例
假设一个程序在一台计算机上运行需要100秒,其中80秒用于乘法操作。如果要将该程序的运行运行速度提高5倍,乘法操作的速度应该改进多少?
根据Amdahl定律计算可得,无论如何改进乘法操作,都无法实现性能提升5倍的目标,该示例也说明加速大概率事件的性能收益也是有上限的
4 功耗墙
4.1 动态功耗
1. 动态功耗是指晶体管开关过程中消耗的能量,是CMOS中主要的功耗来源
2. 动态功耗取决于每个晶体管的负载电容、工作电压和开关频率(开关频率是时钟频率的函数),公式如下,
3. 根据动态功耗公式,降低芯片动态功耗的方法如下,
① 降低时钟频率
② 降低工作电压
说明:由于动态功耗和工作电压的平方呈正比,所以降低电压可以显著降低功耗(e.g. 工作电压降低到原来的1/5,动态功耗则是原来的1/25)
但是降低工作电压会使得晶体管的漏电流问题更加突出,从而增加芯片的静态功耗
4.2 静态功耗
1. 静态功耗是指晶体管在关闭状态下由于漏电流导致的能量消耗,约30% ~ 40%的芯片功耗是由于漏电流引起的
2. 静态功耗取决于工作电压和漏电流,公式如下,
说明1:动态功耗和静态功耗都与晶体管数量呈正相关,即增加晶体管数量会增加功耗
说明2:由于功耗日益重要,SPEC也增加了一组用于评估功耗的基准测试程序,用于评价服务器在不同负载水平下的功耗,下图为Intel Nehalem处理器的测试结果
5 从单处理器向多处理器转变
1. 从2006年开始,所有桌面机和服务器公司都在单片微处理器中加入多个处理器,以追求更大的吞吐率,而不再继续追求降低单个处理器上单个程序的响应时间
2. 程序员如果想要显著地改进响应时间,就必须重写程序以充分利用多处理器的并行优势。程序员必须划分应用,使每个核上同时执行的任务量大致相同,并且尽可能减小调度开销,以免浪费并行带来的性能提升
说明:Amdahl定律同样可以用于说明并行处理器数量的实际限制,即处理器通过增加核数量可以提升性能,但核数量增加到一定程度就无法再提升性能