小土刀

【计算机系统导论】3.2 解构处理器

处理器经过了几十年的发展历程,已经成为了人类历史上最为复杂精巧且强大的设备之一。本节我们就深入处理器的内部来看看,作为人类工程的结晶的处理器之美。


解构指令集处理器设计的三个角度(不同人有不同的视角)

  1. Architecture(ISA) - programmer/complier view
    • opcodes, addressing modes, architected register, IEEE floating point
  2. Implementation(微架构) - processor designer view
    • logical structure or organization that performs the ISA specification
    • pipelining, functional units, caches, physical registers, buses, branch predictors
  3. Realization(Chip) - chip/system designer view
    • physical structure that embodies the implementation
    • gates, cells, transistors, wires, dies, packaging

[Gerrit Blaauw & Fred Brooks, 1981]

然后按照这三个角度进行说明

  • 现代计算机设计原则
  • 处理器级并行
  • 算术逻辑单元(加减乘除、浮点运算)
  • CPU 组成
  • 寄存器组成(用户可见寄存器、控制和状态寄存器)
  • x86 系列处理器(寄存器组成、中断处理)
  • ARM 处理器(处理器组成、模式、寄存器组成、中断处理)

3.1.2 处理器发展历程

参考 http://www.computerhistory.org/microprocessors/

现代处理器硬件的关键技术是硅。与理解集成电路技术同样重要的是理解我们所期望的技术进步速率。在硅技术加快硬件进步的同时,计算机组织的新思想也改进了产品的性价比。其中有连个重要的新思想:第一,在程序中开发并行性,目前的典型方法是借助多处理器;第二,开发存储层次结构的访问局部性,目前的典型方法是通过 cache。

功耗已经取代芯片面积,成为微处理器设计中最重要的资源。保存功耗并且改进性能的需求已经迫使硬件工业向多核微处理器跃进,从而迫使软件工业向并行硬件编程跃进。计算机设计总是以价格和性能来度量的,也包括其他一些重要因素,如功耗、可靠性、成本和可扩展性等。尽管本章的重点放在价格、性能和功耗上,但是最佳的设计应该在特定的应用领域中取得所有因素之间适当的平衡。

现代的高性能微处理器可以在一个时钟周期内发射多条指令。遗憾的是,持续这样的高发射速率是相当困难的。例如,尽管我们又一个单时钟周期可以发射4-6条指令的处理器,只有很少的应用程序能保持每周期发射两条以上指令。这里面主要有两个原因。1)由于使用了流水线,主要的性能平静在于那些不能立即解决的相关性,这就限制了指令间的并行度,因此也就限制了发射速率。虽然对于真正的数据相关而言么有什么的好的解决办法,但是一般情况下硬件或编译器对于相关是否确实存在都不知道,因而也就只能保守地假设相关存在了。一般来说,指令级并行总是有开发空间的,但是因为并行度较为分散,编译器和硬件往往会显得力不从心。2)存储系统中的 miss 同样会使流水线难以满负荷运转。尽管一个访存引起的阻塞可以被掩盖掉,但是有限的指令级并行度同样会使阻塞被掩盖的程度有所下降。

基本组件

  • 算术逻辑单元
  • 浮点运算器
  • 寄存器
  • 处理器缓存
  • 时钟频率
  • 控制单元
  • 短路复用器

微体系结构

一条指令的执行涉及一系列的统称为周期的子步骤。例如,一条指令的执行可由取指、间接寻址、执行和中断周期组成。每个周期又是由一系列更基本的操作(称为微操作)组成。一个单一的微操作可以完成寄存器间的一次传送,寄存器与外部总线的一次传送,或一个简单的 ALU 操作。

处理器的控制器完成两项任务:1)它使得处理器以正在运行的程序所确定的次序来执行微操作;2)它产生引起微操作执行的控制信号。

控制器产生的控制信号引起逻辑门的打开与管理,从而导致寄存器数据的传送和 ALU 的操作。

一种控制器的实现技术是硬布线技术,采用此技术实现的控制器是一个组合电路。当前机器指令支配的输出逻辑信号被转换为一组输出控制信号

缓存

为什么 CPU 有多级缓存?为什么不把所有的缓存放到一起弄成一个大缓存呢?

使用一级缓存的目的是为了快速存取,如果太大,存取速度会变慢,而且会消耗更多电力。所以一级缓存既要足够大到能起做用,又要小到能够快速存取。

L1 数据缓存通常只处理 1 到 8 个字节的数据,但高层级的缓存并不处理单独的字节。在内存中也一样,高层级缓存通常是批发处理数据,以缓存行 cache line 为单位

L1 指令缓存和数据缓存完全不同,就内核而言,它是只读的。(指令内存的写入通常是用非直接的方式先把指令放入高层的缓存,再载入一级指令缓存)。由于这个愿意,指令缓存和数据缓存通常是分隔的。使用通用的 L1 缓存意味着把互相冲突的设计原则糅合在一起,妥协的结果就是任何一个目的都达不到。

从共享的角度考虑,L1 也不能合并。L2 缓存处理大部分的协同工作。L1 缓存优先为 CPU 内核服务。因为是私有的,所以基本不需要协调工作。L2 缓存也是私有的,但是它的工作重心还包括在不打扰内核工作的情况下处理大量的缓存间的数据通信。

L3 缓存是共享资源,需要全局协调。

CPU 架构

  • Von Neumann 架构
  • 哈佛架构
  • 数据流架构

哈佛结构与冯诺依曼结构
https://www.zhihu.com/question/22406681
https://www.zhihu.com/question/21988212

龙芯

https://www.zhihu.com/question/24177758
https://www.zhihu.com/question/19612562
https://www.zhihu.com/question/32031083
https://www.zhihu.com/question/30008964
https://www.zhihu.com/question/21833989

性能与评测

具体就是围绕这个图片,进行讲解

执行时间 = 秒/程序 = 指令数/程序 乘以 时钟周期数/指令 乘以 秒/时钟周期。

$$\frac{1}{Processor\;Performance}=\frac{Time}{Program}$$

$$=\frac{Instructions}{Program}\times\frac{Cycles}{Instruction}\times\frac{Time}{Cycle}$$

这里 $\frac{Instructions}{Program}$ 的单位是指令的条数,属于架构设计的范畴,对应于编译器的设计者。

这里 $\frac{Cycles}{Instruction}$ 的单位是 CPI,属于实现的范畴,对应于处理器的设计者。在 1980 年代(流水线时代)CPI 从 5.0 降到了 1.15,在 1990 年代(超标量时代)CPI 从 1.15 降到了 0.5,在 2000 年代我们开始考虑功耗的问题

这里 $\frac{Time}{Cycle}$ 的单位是时钟周期的时间,对应于芯片设计者

需要根据 https://www.spec.org/benchmarks.html#cpu 的数据源来做一些数据的图,一般来说 y 轴是评测指标,x 轴是 Speed/Frequency(MHz),比较不同的 CPU

执行时间是唯一有效且不可推翻的性能度量方法。人们曾经提出许多其他度量方法,但均已失败告终。有些从一开始就没有反应执行时间,因而是无效的;还有一些只能在有限条件下有效,超出了限制条件则失效,或是没有清晰的说明有效性的限制条件

不同的应用关注计算机系统的不同方面。许多应用,特别是那些运行在服务器上的应用,主要关注 IO 性能,所以此类应用既依赖硬件又依赖软件,对时间最感兴趣。而在其他一些应用中,用户可能对吞吐率、响应时间或两者的复杂组合更为关注(例如最差响应时间情况下的最大吞吐率)。要改进一个程序的性能,必须明确性能的定义,然后通过测量程序执行时间来寻找性能瓶颈。

性能的测量

经典的性能公式

  • Amdahl 定律
  • roofline model

影响处理器性能的因素

评测及功耗

在不同的设备上不同的目标是不一样的

功耗墙

https://www.zhihu.com/question/20783321

捧个钱场?

热评文章