1. 计算机系统漫游

1.1. 信息等于位+上下文

系统中所有的信息, 包括磁盘文件和内存中的程序/用户数据以及网络上的数据, 都是比特组成的. 区分不同数据对象的唯一方法就是我们读到这些数据对象时的 上下文. 比如, 在不同的上下文中, 一个同样的字节序列可能表示一个整数/浮点数/字符串或者机器指令.

1.2. 程序被其他程序翻译成不同的格式

编译: 高级程序语言必须被其他程序转化为一系列的低级机器语言指令, 然后这些指令按照一种可执行目标程序的格式(可执行文件)打包, 并以二进制文件的形式保存起来.

程序编译流程
Figure 1. 程序编译流程

1.3. 硬件组成

  • 总线: 携带信息字节并负责在各个组件间传递.

  • I/O设备: 每个I/O设备通过一个设备控制器(主板上的芯片组)或适配器(插在主板插槽上的卡)与I/O总线相连,

  • 主存: 处理器执行程序时, 用来存放程序和程序处理的数据.

  • 处理器: 解释存储在主存中的指令的引擎. 处理器的核心是程序计数器(PC), PC指向内存中一条指令的地址, 然后处理器从内存中读取指令数据, 解释并执行, 最后更新PC, 使其指向下一条要执行的指令.

1.4. 存储器层次结构

较大的存储设备要比较小的存储设备运行的慢, 快速设备的造价远高于同类的低俗设备.

高速缓存存储器: 作为一个暂存区域, 存放处理器近期可能会需要的信息.

  • CPU寄存器保存最常用的数据.

  • 靠近CPU的小的, 快速的高速缓存存储器作为主存一部分数据和指令的缓冲区域.

  • 主存缓存容量较大的慢速的磁盘上的数据.

  • 本地磁盘常常作为存储在通过网络连接的其他机器的磁盘上的数据的缓冲区域.

Diagram

1.5. 操作系统

1.5.1. 操作系统基本职责

  • 防止硬件被应用程序滥用.

  • 向应用程序提供简单一致的机制来控制硬件设备.

1.5.2. 操作系统管理

  • 进程

  • 线程

  • 虚拟内存

  • 文件

1.6. Amdahl定律

  • 系统执行某应用程序所需要的时间为\$T_(old)\$

  • 系统某部分执行时间占比\$alpha\$

  • 该部分性能提升比例\$k\$

新的总执行时间

\$T_(n\ew)=(1-alpha)T_(old)+alphaT_(old)/k=T_(old)*((1-alpha)+alpha/k)\$

加速比

\$S=T_(old)/ T_(n\ew)=1/((1-alpha)+alpha/k\$

当\$k->oo\$时, 加速比最多能达到 \$1/(1-alpha)\$

2. 存储器层次结构

2.1. 随机访问存储器

2.1.1. SRAM

只要有电, SRAM存储器就能永远保持它的值.

2.1.2. DRAM

DRAM存储单元对干扰非常敏感, 当电容的电压被扰乱后, 它就永远不会恢复到原来的状态了.

每个DRAM芯片被分为\$d\$个超单元, 排列成r行c列, 每个超单元有w位信息, 所以一个DRAM可以存储\$d*w\$位信息.

2.1.3. SRAM和DRAM区别

每位晶体管数 相对访问时间 数据是否持久化 敏感的 相对花费 应用

SRAM

6

1x

1000x

高速缓存存储器

DRAM

1

10x

1x

主存

2.1.4. 常规DRAM获取数据流程

  1. 每个DRAM芯片被连接到内存控制器的电路, 这个电路可以一次传送w位到对方.为了读出超单元\$(i,j)\$的内容,

  2. 内存控制器首先发送行地址\$i\$, DRAM将行\$i\$的内容复制到内部行缓冲区.

  3. 接下来内存控制器发送列地址\$j\$, DRAM将内部行缓冲区的第\$j\$列内容发送给内存控制器.

2.1.5. 内存模块获取数据流程

  1. 每个内存模块插入8个DRAM芯片.

  2. 内存控制器将内存地址A转换为超单元地址\$(i,j)\$, 将它发送到内存模块.

  3. 内存模块将地址\$(i,j)\$广播到每个DRAM芯片, 每个DRAM芯片响应其地址\$(i,j)\$的内容.

  4. 内存模块收集这些输出并合并成64位的字发送给内存控制器.

2.2. CPU访问主存

数据流通过 总线 在处理器和DRAM主存之间来回传递.每个数据传送的步骤被称为 总线事务 ,其中读事务从主存传递数据到CPU, 写事务从CPU传递数据到主存.

2.2.1. 读事务

👉 movq A, %rax 将内存地址A的内容写入到寄存器rax

  1. CPU将地址A放到系统总线上.

  2. I/O桥将信号传递到内存总线

  3. 主存根据内存总线上的地址读出数据写到内存总线上.

  4. I/O桥将内存总线信号翻译成系统总线信号, 传递到系统总线上.

  5. CPU从系统总线上读出数据, 复制到%rax寄存器内.

2.2.2. 写事务

👉 movq %rax, A 寄存器%rax的内容写到主存地址A

  1. CPU将A的地址写到系统总线, 传递给I/O桥, I/O传递到内存总线上.

  2. 内存从内存总线读出地址, 并等待数据到达.

  3. CPU将%rax寄存器的数据复制到系统总线.

  4. 主存从内存总线读出数据写到A地址中.

2.3. 磁盘存储

2.3.1. 磁盘构造

  • 磁盘由盘片构成.

  • 每个盘片都有两个表面.

  • 每个表面都有若干条磁道.

  • 每个磁道有若干组扇区.

  • 每个扇区能存储若干个字节.

磁盘容量 = 盘片数 * 每个盘片表面数 * 每个表面磁道数 * 每个磁道扇区数 * 每个扇区字节数.

2.3.2. 磁盘访问时间

  • 寻道时间(seek): 磁盘震动臂移动到磁道上的时间.

  • 旋转时间(rotate): 磁盘旋转使得读写头落在对应扇区上所需的时间. \$T_(AvgRotation)=1/2 * 1/(RPM) * (60s)/min\$

  • 传送时间(transfer): 驱动器读写数据的时间. \$T_(AvgTransfer)=1/2*1/(RPM) * 1/((扇区数)/(磁道)) * (60s)/min\$

2.3.3. 磁盘访问流程

  1. 磁盘控制器将所有扇区排成B个逻辑块序列, 并维护逻辑块序号和扇区之间的关系.

  2. 当操作系统想要执行一个I/O操作时, 操作系统会发一个命令到磁盘控制器, 让它读某个逻辑块号, 磁盘控制器将逻辑块号翻译成(盘面,磁道,扇区)三元组.

  3. 磁盘控制器根据这个三元组将读写头移动到相应的柱面, 然后等待扇区移动到读写头下. 将读写头感应到的位放到磁盘控制器的缓冲区内, 随后将数据复制到主存(DMA).

  4. 磁盘控制器给CPU发送一个中断信号来通知CPU. CPU会暂停它正在做的工作, 记录下这次I/O已经完成, 然后返回刚刚被中断的地方.

2.4. 高速缓存

2.4.1. 结构

  • 每个存储器地址有\$m\$位, 形成\$2^m\$个不同的地址.

  • 高速缓存被组织成一个有\$S=2^s\$个高速缓存组, 每个高速缓存组有\$E\$个缓存行.

  • 每个缓存行由\$B=2^b\$个数据块, 1个有效状态位, t=m-(b+s)个标记位组成.

常见缓存结构
  • 直接映射高速缓存(E=1)

  • 组相连高速缓存(1<E<C/B)

  • 全相连高速缓存(S=1)

2.4.2. 缓存读取流程

  1. 内存地址由三部分组成: t位标记+m位组索引+b位块偏移.

  2. 根据组索引确定缓存落在哪个组中.

  3. 根据标记位确定缓存落在哪一行.

  4. 根据块偏移确定缓存数据.

2.4.3. 伪共享

数据一批元素被load到高速缓存时, 后面因为步长原因导致后一批元素会覆盖前面元素的缓存行数据, 循环读时导致每次load时都会刷新缓存.