《计算机体系结构基础》杂记(2)

记录下读胡伟武的《计算机体系结构基础》的一些知识点和扩展,第三部分,主要是计算机硬件结构部分。
1、冯·诺依曼结构
是 1945 年匈牙利籍数学家冯·诺依曼受宾夕法尼亚大学研制的 ENIAC 计算机结构的启发提出的,是世界上第一个完整的计算机体系结构。
image
冯·诺依曼结构的主要特点是:
➀ 计算机由存储器、运算器、控制器、输入设备和输出设备五部分组成,其中运算器和控制器合称为中央处理器(Central Processing Processor,简称CPU)。
➁ 存储器是按地址访问的线性编址的一维结构,每个单元的位数固定。
➂ 采用存储程序方式,即指令和数据不加区别混合存储在同一个存储器中
➃ 控制器通过执行指令发出控制信号控制计算机的操作。指令在存储器中按其执行顺序存放,由指令计数器指明要执行的指令所在的单元地址。指令计数器一般按顺序递增,但执行顺序可按运算结果或当时的外界条件而改变。
➄ 以运算器为中心,输入输出设备与存储器之间的数据传送都经过运算器。冯·诺依曼计算机的工作原理如图5.1所示。
随着技术的进步,冯·诺依曼结构得到了持续的改进,主要包括以下几个方面:
由以运算器为中心改进为以存储器为中心。使数据的流向更加合理,从而使运算器、存储器和输入输出设备能够并行工作。
➁ 由单一的集中控制改进为分散控制。计算机发展初期,工作速度很低,运算器、存储器、控制器和输入输出设备可以在同一个时钟信号的控制下同步工作。现在运算器、内存与输入输出设备的速度差异很大,需要采用异步方式分散控制。
➂ 从基于串行算法改进为适应并行算法。出现了流水线处理器、超标量处理器、向量处理器、多核处理器、对称多处理器(SymmetricMultiprocessor,简称 SMP)、大规模并行处理机(Massively Parallel Processing,简称 MPP)和机群系统等。
➃ 出现为适应特殊需要的专用计算机,如图形处理器(Graphic Processing Unit,简称 GPU)、数字信号处理器(Digital Signal Processor,简称 DSP)等。
➄ 在非冯·诺依曼计算机的研究方面也取得一些成果,如依靠数据驱动的数据流计算机、图归约计算机等。
2、哈佛结构
哈佛结构把程序和数据分开存储,为冯·诺依曼结构的一个变种,控制器使用两条独立的总线读取程序和访问数据,程序空间和数据空间完成分开。在嵌入式领域,哈佛结构得到了广泛应用。
哈佛结构并没有改变冯·诺依曼结构存储程序和指令驱动执行的本质,它只是冯·诺依曼结构的一个变种,并不是独立于冯·诺依曼结构的一种新型结构。
3、运算器
运算器是计算机中负责计算(包括算术计算和逻辑计算等)的部件。

4、控制器
控制器是计算机中发出控制命令以控制计算机各部件自动、协调地工作的装置。控制器控制指令流和每条指令的执行,内含程序计数器和指令寄存器等。程序计数器存放当前执行指令的地址,指令寄存器存放当前正在执行的指令。指令通过译码产生控制信号,用于控制运算器、存储器、IO 设备的工作以及后续指令的获取。
计算机执行指令一般包含以下过程:从存储器取指令并对取回的指令进行译码,从存储器或寄存器读取指令执行需要的操作数,执行指令,把执行结果写回存储器或寄存器。上述过程称为一个指令周期。
常见的提高流水线效率的技术包括转移预测技术、乱序执行技术、超标量(又称为多发射)技术等。

5、存储器
存储器存储程序和数据,又称主存储器或内存,一般用动态随机访问存储器(Dynamic Random Access Memory,简称DRAM)实现。
存储器的主要评价指标为存储容量和访问速度。
image

Cache 是内存的映像,其内容是内存内容的子集,处理器访问 Cache 和访问内存使用相同的地址。从 20 世纪 80 年代开始,RISC 处理器就开始在处理器芯片内集成 KB 级的小容量 Cache。现代处理器则普遍在片内集成多级 Cache,典型的多核处理器的每个处理器核中一级指令 Cache 和数据Cache 各几十 KB,二级 Cache 为几百 KB,而多核共享的三级 Cache 为几 MB 到几十 MB。现代处理器访问寄存器时一拍可以同时读写多个数据,访问一级 Cache 延迟为 1‑4 拍,访问二级 Cache 延迟为10‑20 拍,访问三级 Cache 延迟为 40‑60 拍,访问内存延迟为 100‑200 拍。
内存
image

影响SDRAM芯片读写速度的因素有两个:行缓冲局部性(Row Buffer Locality,简称RBL)和Bank级并行度(Bank Level Parallelism,简称 BLP)。

image

6、输入/输出设备
处理器通过读写 IO 设备控制器中的寄存器来访问及控制 IO 设备。高速 IO 设备可以在处理器安排下直接与主存储器成批交换数据,称为直接存储器访问(Directly Memory Access,简称DMA)。
处理器可以通过查询设备控制器状态与 IO 设备进行同步,也可以通过中断与 IO 设备进行同步。
GPU 的作用是对图形 API 定义的流水线实现硬件加速,主要包括以下几个阶段:
・ 顶点读入(Vertex Fetch):从内存或显存中取出顶点信息,包括位置、颜色、纹理坐标、法向量等属性
・ 顶点渲染(Vertex Shader):对每一个顶点进行坐标和各种属性的计算
・ 图元装配(Primitive Assembly):将顶点组合成图元,如点、线段、三角形等
・ 光栅化(Rasterization):将矢量图形点阵化,得到被图元覆盖的像素点,并计算属性插值系数以及深度信息
・ 像素渲染(Fragment Shader):进行属性插值,计算每个像素的颜色
・ 逐像素操作(Per‑Fragment Operation):进行模板测试、深度测试、颜色混合和逻辑操作等,并最终修改渲染缓冲区

磁性材料具有断电记忆功能,可以长时间保存数据;磁性材料的存储密度高,可以搭建大容量存储系统;同时,磁性材料的成本很低。
硬盘就是一种磁性存储介质。
硬盘的构造原理为:将磁性材料覆盖在圆形碟
片(或者说盘片)上,通过一个读写头(磁头)悬浮在碟片表面来感知存储的数据。通过碟片的旋转和磁头的径向移动来读写碟片上任意位置的数据。碟片被划分为多个环形的轨道(称为磁道,Track)来保存数据,每个磁道又被分为多个等密度(等密度数据)的弧形扇区(Sector)作为存储的基本单元。磁盘的内部构造如图5.5所示。硬盘在工作时,盘片是一直旋转的,当想要读取某个扇区的数据时,首先要将读写头移动到该扇区所在的磁道上,当想要读写的扇区旋转到读写头下时,读写头开始读写数据。
image

闪存(Flash Storage)是一种半导体存储器,它和磁盘一样是非易失性的存储器,但是它的访问延迟却只有磁盘的千分之一到百分之一,而且它尺寸小、功耗低,抗震性更好。常见的闪存有SD卡、U盘和SSD固态磁盘等。
使用闪存技术构建的永久存储器存在一个问题,即闪存的存储单元随着擦写次数的增多存在损坏的风险。为了解决这个问题,大多数NAND型闪存产品内部的控制器采用地址块重映射的方式来分布写操作,目的是将写次数多的地址转移到写次数少的块中。该技术被称为磨损均衡(WearLeveling)。闪存的平均擦写次数在 10 万次左右。

7、现代计算机系统的硬件结构主要包括了中央处理器、图形处理器、北桥及南桥等部分。
CPU‑GPU‑北桥‑南桥四片结构
image

CPU‑北桥‑南桥三片结构
image
三片结构与四片结构最大的区别是,前者 GPU 功能被集成到北桥,即一般所说的集成显卡。

CPU‑弱北桥‑南桥三片结构
image
存储墙问题:伴随着处理器核计算性能的大幅提升,存储器的性能提升却显得幅度较小,这两者的差异导致计算机系统性能受到存储器系统发展的制约。
因此,对计算机系统性能影响显著的内存控制器开始被集成到 CPU 芯片中,从而大幅降低了内存访问延迟,提升了内存访问带宽,这在一定程度上缓解了存储墙问题。
北桥的功能被弱化,主要集成了 GPU、显示接口、高速 IO 接口(例如 PCIE 接口等)。

CPU‑南桥两片结构
image
随着芯片集成度的进一步提高,图形处理器也开始被集成到 CPU 芯片中,于是,北桥存在的必要性就进一步降低,开始和南桥合二为一,形成 CPU‑南桥结构,

SoC 单片结构
image

8、使用 DMA 进行传输的一般过程为:
1)处理器为 DMA 请求预先分配一段地址空间。
2)处理器设置DMA 控制器参数。这些参数包括设备标识、数据传送的方向、内存中用于数据传送的源地址或目标地址、传输的字节数量等。
3)DMA控制器进行数据传输。DMA控制器发起对内存和设备的读写操作,控制数据传输。DMA传输相当于用 IO 设备直接读写内存。
4)DMA 控制器向处理器发出一个中断,通知处理器数据传送的结果(成功或者出错以及错误信息)。
5)处理器完成本次 DMA 请求,可以开始新的 DMA 请求。
image
从上面两个例子中可以看到,PIO方式和DMA方式处理的流程一致,区别在于:首先键盘的数据是被记录在 IO 设备本身的,而网卡的数据则直接由网卡写入内存之中;其次 CPU 处理时,对键盘是直接从 IO 寄存器读数据,而对网卡则直接从内存读数据。

9、总线的含义可以分为以下几个层级:
1)机械层。接口的外形、尺寸、信号排列、连接线的长度范围等。
2)电气层。信号描述、电源电压、电平标准、信号质量等。
3)协议层。信号时序、握手规范、命令格式、出错处理等。
4)架构层。硬件模型、软件架构等。

10、AXI AHB APB ASB
可单独整理一篇。
11、内存总线
image
image
DRAM 存储单元是按照 Bank、行、列来组织的,因此对 DRAM 的寻址是通过 bank 地址、行地址和列地址来进行的。

12、系统总线
系统总线通常用于处理器与桥片的连接,同时也作为多处理器间的连接以构成多路系统。
英特尔处理器所广泛采用的 QPI(Quick Path Interconnect)接口及在 QPI 之前的 FSB(Front Side Bus),还有 AMD 处理器所广泛采用的 HT(HyperTransport)接口都属于系统总线。
image

- HT 包格式
HT 总线的传输以包为单位。按照传输的类型,首先分为控制包和数据包两种。控制包和数据包使用 CTL 信号区分,当 CTL 信号为高时,表示正在传输一个控制包,当 CTL 信号为低时,表示正在传输一个数据包。数据包依附于最近的一个带数据的控制包。
控制包根据传输的内容,再分为三种不同的包格式,分别为信息包、请求包和响应包。
信息包的作用是为互连的两端传递底层信息,本身不需要流控。这意味着对于信息包,无论何时都是可以被接收并处理的。流控信息就是一种典型的信息包。信息包的格式如表6.4所示。
image

HT 也是采用 DDR 传输,即双倍数据率传输,在时钟的上升、下降沿各传一组数据。每种包大小都是 4 字节的倍数。
请求包主要是读请求和写请求。其中读请求不需要数据,而写请求需要跟随数据包。
image

响应包大小为 4 字节。与请求包类似,写响应包不需要数据,而读响应包需要跟随数据包。
image

13、设备总线

14、PCIE总线
PCIE 总线的传输同样以包(事务层包,Transaction Level Packet,简称 TLP)为单位,
PCIE 同样采用了流控机制来消除总线握手。


15、无论采用何种指令系统的处理器,复位后的第一条指令都会从一个预先定义的特定地址取回。
处理器的执行就从这条指令开始。处理器的启动过程,实际上就是一个特定程序的执行过程。这个程序我们称之为固件,又称为BIOS(Basic Input Output System,基本输入输出系统)。对于LoongArch,处理器复位后的第一条指令将固定从地址 0x1C000000 的位置获取。这个地址需要对应一个能够给处理器核提供指令的设备,这个设备以前是各种 ROM,现在通常是闪存(Flash)。从获取第一条指令开始,计算机系统的启动过程也就开始了。

16、处理器核初始化
初始化,实际上是将计算机内部的各种寄存器状态从不确定设置为确定,将一些模块状态从无序强制为有序的过程。简单来说,就是通过 load/store 指令或其他方法将指定寄存器或结构设置为特定数值。
防止什么问题?
有可能导致取指猜测错误,发出一个对非法地址的猜测请求。如果此时处理器没有对猜测访问通路进行控制或初始化,就可能会发生严重问题,例如猜测访问落入地址空洞而失去响应并导致死机等。

17、处理器复位
处理器的第一条指令实际上是由复位信号控制的,但受限于各种其他因素,复位信号并没有对处理器内部的所有部分进行控制,例如 TLB、Cache 等复杂结构, 而是只保证从取指部件到 BIOS取指令的通路畅通
需要指出的是,处理器复位后先是通过频率为几十兆赫兹(MHz)以下的低速设备取指令,例如 SPI 或 LPC 等接口。一拍只能取出 1 比特(SPI)或 4 比特(LPC),而一条指令一般需要 32 比特。对于吉赫兹(GHz)的高性能处理器来说,几千拍才能执行一条指令,相当于在城市空荡荡的大街上只有一个人在行走,这时候的指令很 “孤独”。

18、调试接口初始化
image
对串口的初始化操作实际上是处理器对串口执行一连串约定好的IO操作。在X86结构下,IO地址空间与内存地址空间相互独立,IO 操作与访存操作是通过不同的指令实现的。
MIPS 和 LoongArch等结构并不显式区分 IO 和内存地址,而是采用全局编址,使用地址空间将 IO 和内存隐式分离,并通过地址空间或 TLB 映射对访问方式进行定序及缓存等的控制。

理解 IO 与内存访问的区别:
内存空间对应的是存储器,存储器不会发生存储内容的自行更新。也就是说,如果处理器核向存储单元 A 中写入了 0x5a5a 的数值,除非有其他的主控设备(例如其他的处理器核或是其他的设备 DMA)对它也进行写入操作,否则这个 0x5a5a 的数值是不会发生变化的。
IO 空间一般对应的是控制寄存器或状态寄存器,是受 IO 设备的工作状态影响的。此时,写入的数据与读出的数据可能会不一致,而多次读出的数据也可能不一致,其读出数据是受具体设备状态影响的。例如,对串口的线路状态寄存器(寄存器偏移0x5)的读取在不同的情况下会产生不同的返回值。该寄存器定义如表7.1所示。
IO 寄存器的行为与具体的设备紧密相关,每种 IO 设备都有各自不同的寄存器说明,需要按照其规定的访问方式进行读写,而不像内存可以进行随意的读写操作。

19、TLB初始化
TLB作为一个地址映射的管理模块,主要负责操作系统里用户进程地址空间的管理,用以支持多用户多任务并发。
初始化的过程实际上就是将整个 TLB 表项清 0的过程。
需要特别说明的是,在 LoongArch 架构中,实际上并不需要使用这样的指令来完成这个过程,而可以直接使用 INVTLB 0,$r0,$r0 这一条指令,由硬件完成类似的循环清空操作。
越来越多的处理器已经实现了在芯片复位时由硬件进行 TLB 表项的初始化,这样在 BIOS 代码中可以不用再使用类似的软件初始化流程。

20、Cache初始化
在系统复位之后,Cache 同样也处于一个未经初始化的状态,也就是说 Cache 里面可能包含残留的或随机的数据,如果不经初始化,对于 Cache 空间的访问也可能会导致错误的命中。
在进行 Cache 初始化时要考虑所有需要的层次。
Cache 的组织结构主要包含标签(Tag)和数据(Data)两个部分,Tag 用于保存 Cache 块状态、
Cache 块地址等信息,Data 则保存数据内容。大多数情况下对 Cache 的初始化就是对 Tag 的初始化,只要将其中的 Cache 块状态设置为无效,其他部分的随机数据就不会产生影响。
image
完成Cache空间的初始化并跳转至Cache空间运行也标志着处理器的核心部分,或者说体系结构相关的初始化部分已经基本完成。接下来将对计算机系统所使用的内存总线和 IO 总线等外围部分进行初始化。

21、总线接口初始化
初始化就是将某些寄存器通过 load/store 指令或是其他的方法设置为期望数值的过程。这些不同的配置情况要求在计算机系统启动时能够进行有针对性的初始化。

  • UDIMM RDIMM
    UDIMM(Un‑buffered DIMM,非缓冲型内存模组)改为 RDIMM(Registered DIMM,寄存型内存模组)

22、内存初始化
以在计算机系统启动的过程中需要先获取内存的配置信息,再根据该信息对内存控制器进行配置。
获取这些信息是程序通过 I2C 总线对外部内存条的 SPD 芯片进行读操作来完成的。SPD 芯片也相当于一个 Flash 芯片,专门用于存储内存条的配置信息。

与 Cache 初始化类似的是,内存初始化并不涉及其存储的初始数据。与 Cache 又有所不同的地方在于,Cache 有专门的硬件控制位来表示 Cache 块是否有效,而内存却并不需要这样的硬件控制位。内存的使用完全是由软件控制的,软件知道其访问的每一个地址是否存在有效的数据。而Cache是一个硬件加速部件,大多数情况下软件并不需要真正知道而且也不希望知道其存在,Cache的硬件控制位正是为了掩盖内存访问延迟,保证访存操作的正确性。

内存控制器的初始化包括两个相对独立的部分,一是根据内存的行地址、列地址等对内存地址映射进行配置,二是根据协议对内存信号调整的支持方式对内存读写信号相关的寄存器进行训练,以保证传输时的数据完整性。
在内存初始化完成后,可能还需要根据内存的大小对系统可用的物理地址空间进行相应的调整和设置。

23、IO总线初始化
在IO总线初始化时,做了三件事:
一是对IO 总线的访问地址空间进行设置,划定设备的配置访问空间、IO 访问空间和 Memory访问空间;
二是对 IO 设备的 DMA 访问空间进行规定,对处理器能接收的 DMA 内存地址进行设置;
三是对 HyperTransport 总线进行升频,从复位时 1.0 模式的 200MHz 升频到了 3.0 模式的 2.0GHz,并将总线宽度由 8 位升至 16 位

24、通用的设备枚举和驱动加载的过程
在 PCI 协议下,IO 的系统空间分为三个部分:配置空间、IO 空间和 Memory 空间。配置空间存储设备的基本信息,主要用于设备的探测和发现;IO 空间比较小,用于少量的设备寄存器访问;Memory 空间可映射的区域较大,可以方便地映射设备所需要的大块物理地址空间。
配置空间的地址偏移由总线号、设备号、功能号和寄存器号的组合得到,通过对这个组合的全部枚举,可以很方便地检测到系统中存在的所有设备。
image

image

对 PCI 设备的探测和驱动加载是一个递归调用过程,大致算法如下:
1)将初始总线号、初始设备号、初始功能号设为 0。
2)使用当前的总线号、设备号、功能号组成一个配置空间地址,这个地址的构成如图7.3所示,使用该地址,访问其 0 号寄存器,检查其设备号。
3)如果读出全 1 或全 0,表示无设备。
4)如果该设备为有效设备,检查每个 BAR 所需的空间大小,并收集相关信息。
5)检测其是否为一个多功能设备,如果是则将功能号加 1 再重复扫描,执行第 2 步。
6)如果该设备为桥设备,则给该桥配置一个新的总线号,再使用该总线号,从设备号 0、功能号 0 开始递归调用,执行第 2 步。
7)如果设备号非 31,则设备号加 1,继续执行第 2 步;如果设备号为 31,且总线号为 0,表示扫描结束,如果总线号非 0,则退回上一层递归调用。

25、多核启动过程
我们将多核处理器中的一个核定为主核,其他核定为从核。主核除了对本处理器核进行初始化之外,还要负责对各种总线及外设进行初始化;而从核
只需要对本处理器核的私有部件进行初始化,之后在启动过程中就可以保持空闲状态,直至进入操作系统再由主核进行调度。

主核的启动过程与前三节介绍的内容基本是一致的。但在一些重要的节点上则需要与从核进行同步与通信,或者说通知从核系统已经到达了某种状态。

26、核间同步和通信

  • 核间中断
    核间中断也是利用一组 IO 寄存器实现的。
    通过将目标核的核间中断寄存器置 1 来产生一个中断信号,使目标核进入中断处理。中断处理的具体内容则是通过内存进行交互的。内核中为每个
    核维护一个队列(内存中的一个数据结构),当一个核想要中断其他核时,它将需要处理的内容加入目标核的这个队列,然后再向目标核发出核间中断(设置其核间中断寄存器)。当目标核被中断之后,开始处理其核间通信队列,如果其间还收到了更多的核间中断请求,也会一并处理。
    为什么Linux内核中的核间中断处理不通过信箱寄存器进行呢?
    首先信箱寄存器只有一组,也就是说如果通过信箱寄存器发送通信消息,在这个消息没被处理之前,是不能有其他核再向其发出新的核间中断的。这样无疑会导致核间中断发送方的阻塞。另外,核间中断寄存器实际上是 IO寄存器,前面我们提到,对于 IO 寄存器的访问是通过不经缓存这种严格访问序的方式进行的,相比于Cache访问方式,不经缓存读写效率极其低下,本身延迟开销很大,还可能会导致流水线的停顿。因此在实际的内核中,只有类似休眠唤醒这种特定的同步操作才会利用信箱寄存器进行,其他的同步通信操作则是利用内存传递信息,并利用核间中断寄存器产生中断的方式共同完成的。
posted @ 2023-01-28 15:25  zhmiyo  阅读(101)  评论(0编辑  收藏  举报