加速经常性事件
加速经常性事件远比优化罕见事件更能提高性能。更有讽刺意味的是,经常性事件往往比罕见事件更简单,因而更容易提升。
举例:
- 原码与补码:原码肯定也可以作为计算机的存储方式,但是它需要对符号位和数值位分别操作,不够快速。
- 大量使用缓存技术:利用空间局部性与时间局部性。把在未来更可能用到的数据放到更高层的存储结构中。
- CPU多周期与单周期:单周期CPU的指令周期取决于最长的指令,耗时短的指令得不到加速。而多周期CPU将指令周期进一步细分为机器周期,一定程度上使得指令执行不必受最长指令的限制,换言之,简单指令的执行得到加速。
- RISC与CISC:
CISC:大量的复杂指令、指令格式不规整、控制器采用微程序、对访存不做限制、冗余的寻址方式。
RISC则选择用简单指令代替复杂指令,大多数指令的执行时间限制在1个机器周期,严格限制访存。 - 微程序与硬布线:硬布线方式砍去了微程序方式的取微指令、微指令译码等操作。加速了微操作的执行。
- 将经常用到的操作加到指令系统里:
lu12i、addi指令方便处理立即数,不必把常量放入主存中。
jirl、bl等链接指令加速函数调用过程,方便返回地址的读取。
立即寻址方式使得对常量的操作减少一次访存。
PC相对寻址方式加速分支指令的执行。
基址寻址方式加速数组的处理。
函数调用中大量使用寄存器传递参数而非内存
Amdahl定律(经常性事件占据的执行时间占的比重更大):
改 进 后 的 执 行 时 间 = 受 改 进 影 响 的 执 行 时 间 改 进 量 + 不 受 影 响 的 执 行 时 间 改进后的执行时间 = \frac {受改进影响的执行时间}{改进量} + 不受影响的执行时间 改进后的执行时间=改进量受改进影响的执行时间+不受影响的执行时间
通过并行提高性能
从计算机诞生开始,计算机设计者就通过并行执行操作来提高性能。并行操作的实现依赖大量的硬件冗余。
举例:
- CPU中的指令流水线、超标量技术等等。
- 运算器中的并行操作:如常见的加法器并行进位,通过设备冗余实现快速乘法(使得64位数的乘法需要6次64位加法而非64次长加法),子字并行技术(将64位加法器分割,使其可以同时做两个32位加法或8个字节加法)。
- IO设备的并行操作:使用DMA方式、IO通道方式代替中断方式、程序查询方式,使得数据传送过程中CPU可以执行其他指令。
- 总线方面:使用多根地址线、数据线而不是一根。
- 存储器中的并行操作:最具有代表性的应该是猝发传输技术,允许CPU指定传输的首地址和传输长度来传输大批量数据,使得数据准备过程并行进行。还有双端口存储器、交叉存储技术、刷新周期执行DMA操作等等。
详见我的另一篇博客:DRAM内存 与SRAM的比较和加速方法 计算机组成原理
通过流水线提高性能
流水线是并行性的一个特例。小镇失火时,小镇的居民们排成一排通过水桶接力快速将水桶从水源传至火场,而不是每个人都在来回奔跑。
详见我的另一篇博客:计算机组成与设计 流水线学习笔记
通过预测提高性能
在某些情况下,如果假定从误预测恢复执行代价不高并且预测的准确率相对较高,则通过猜测的方式提前开始某些操作,要比等到确切知道这些操作应该启动时才开始要快一些。
举例:
- 流水线PC:因为分支指令的存在,流水线存在控制冒险的问题。引入了动态分支预测技术。一种实现方案是引入分支历史表,根据历史信息动态觉决定是否跳转。
- Cache映射:CPU要查找的数据,都默认去Cache中找,如果Cache找不多,再去主存中找。
存储器层次
计算机的设计者引入存储层次解决存储容量与存储速度的矛盾。速度最快、容量最小、价格最昂贵的在最上层。
相邻层次之间进行数据传输,以块为单位。两个核心技术是Cache和虚拟存储。
Cache是使用Cache作为主存的映射,虚拟存储技术是使用主存作为辅存的映射。因为层次不同,二者的工作机制也有不同。
Cache | 虚拟存储 | |
---|---|---|
映射策略 | 组相联 | 全相联 |
块容量 | 较小 | 较大 |
例外处理 | 硬件实现 | 软件实现 |
写会策略 | 写穿透、写返回 | 写返回 |
通过冗余提高可靠性
计算机不仅需要速度快,还要工作可靠。由于任何一个物理器件都有可能失效,因此可以通过使用冗余部件的方式提高系统的可靠性(dependable),冗余部件可以替换失效部件并可以帮助检测错误。
举例:
- 奇偶校验与循环冗余校验:在存储数据时除了数据位还要有冗余位。因为数据传输中的错误是可能的,冗余位使得接收方可以发现错误。如果冗余位足够多,接收方甚至可以自己更正数据而不需要发送方的重传。
- 中断:当检测到系统故障时,使得错误可以及时传递给CPU。如除0问题,溢出问题等等,让CPU对这些错误做处理。此外还有系统端电、磁盘坏道等等。中断机制提高了计算机处理异常的能力。
- 总线异步通信中的互锁信号:异步通信有三种——非同步、半同步与全同步。其中半同步需要一次握手,全同步需要两次握手。握手信号的存在使得总线传输更为可靠。
- 锁与解锁:如果两个任务相互独立,那么并行执行比较容易,但通常任务之间需要协作。协作意味着一些任务正在写入其他任务必须读取的值。需要知道任务何时完成写入以便其他任务安全地读出,因此任务之间需要同步。
为支撑这种并行同步的实现,硬件位寄存器引入了锁变量,如果一个任务正在操作一个不希望别的任务操作的寄存器,它就给寄存器上锁。
面向摩尔定律的设计
摩尔定律指出单芯片上的集成度没18-24个月翻一番。计算机设计者必须预测其设计完成时的工艺水平,而不是设计开始时的。
在过去,程序员可以依赖摩尔定律,无需修改一行代码,就能实现程序每18个月性能翻一番。
但现在,摩尔定律接近失效。由于微处理器的功耗已经达到物理极限,微处理器的设计也由单处理器向多处理器转变,现在的程序员需要掌握并行编程能力以充分利用多处理器的优势。
并行就是未来!
使用抽象简化设计
提高硬件和软件生产率的主要技术之一是使用抽象(abstraction)来表示不同的设计层次,在高层次中看不到低层次的细节,只能看到一个简化的模型。
硬件和软件设计者都采用分层的方式构建计算机系统。
最具代表性的抽象是冯诺依曼体系结构。需要提及的是,随着制程的不断下降,人类计算机不久将进入量子世界,遵守的也将是量子世界的数学。冯诺依曼体系结构是否会被颠覆也是一个未知数。