计算机组成与设计课程复习
与 CSAPP 中类似的部分做了忽略或者简化
性能的度量
知识回顾
对于某个计算机 X,定义性能和执行时间的关系表达式:
\[\text{性能}_X = \frac{1}{\text{执行时间}_X} \]描述时钟周期和时钟频率的关系:
\[\text{时钟周期} = \frac{1}{\text{时钟频率}} \]对于某个程序,CPU执行时间的计算公式:
\[ \text{CPU执行时间} = \text{CPU时钟周期数} \times \text{时钟周期} \\ = \text{CPU时钟周期数} \times \frac{1}{\text{时钟频率}} \]指令平均时钟周期数
\[\text{CPI} = \frac{\text{CPU时钟周期数}}{\text{指令数}} \]基本性能公式
\[\text{CPU执行时间} = \text{CPI} \times \text{指令数} \times \text{时钟周期} = \frac{\text{CPI} \times \text{指令数}}{\text{时钟频率}} \]SPEC 分值
\[\text{SPECint}_X = \frac{\text{基准测试程序在 X 上的执行时间}}{\text{基准测试程序在标准机器上的执行时间} \times 100} \]课后练习
解答思路:
a. $ \text{时钟周期} = \frac{1}{\text{时钟频率}} $
$ \text{每秒执行的指令数} = \frac{1}{{\text{时钟周期}}\times{\text{CPI}}} $
b. $ \text{时钟周期数} = \text{时钟频率} \times \text{CPU执行时间} $
$ \text{指令数} = \frac{\text{时钟周期数}}{\text{CPI}} $
c. $ \text{时钟频率} = \frac{1}{\text{时钟周期}} = \frac{CPI \times \text{指令数}}{\text{CPU执行时间}} $
解答思路:
a. $ \text{整体CPI} = \Sigma \text{CPI}_i \times \text{比例}_i $
b. $\text{时钟周期总数} = \text{整体CPI} \times \text{指令总数} $
RISC-V 指令集
知识回顾
存储程序概念
lui 指令:取左移 12 位后的 20 位立即数,目的是给一个寄存器赋一个 32 位的值;比如:将 0x12345678 放入 x19
lui x19, 0x12345
addi x19, x19, 0x678
通过使用 x0
寄存器,跳转-链接指令也可以实现无条件跳转
jal x0, 0x1000
在 RISC-V 中,栈指针是寄存器 x2
,也称为 sp
;按照历史惯例,栈按照从高到低的方向增长
x5 ~ x7, x28 ~ x31
:caller-saved
寄存器,称为临时寄存器 t0 ~ t6 (temporary)
x8 ~ x9, x18 ~ x27
:callee-saved
寄存器,称为保存寄存器 s0 ~ s11 (saved)
x10 ~ x17
:参数寄存器 a0 ~ a7 (argument)
关于 RISC-V 对过程的支持,以递归实现的阶乘函数为例:
观察栈的变化以及 x1
的使用
RISC-V 的内存(memory)存储模型
一些 RISC-V 编译器使用帧指针 fp (frame pointer)
或者寄存器 x8
来指向过程帧(在一个过程中存储在栈上的寄存器或者局部变量,也称活动记录)的第一个字(实际上就是保存了一个地址)
保留加载字(lr.w
)和条件存储字(sc.w
)指令,用于实现原子操作;这两个指令按序使用,如果保留加载指令指定的内存位置的内容在条件存储指令执行到同一地址前发生了变化,则条件存储指令失败且不会把数据写回内存。这是一种指令对的方法,用于实现原子(atomic)操作(在两个操作之间不能插入其他操作,就像原子不可分一样)。
比如,实现一个原子交换(atomic swap)操作:
again: lr.w x10, (x20)
sc.w x11, x23, (x20)
bne x11, x0, again
addi x23, x10, 0
lr.w
做了两件事:1. 从 x20
指向的内存位置读取一个字到 x10
;2. 把 x20
指向的内存位置设置保留标记
sc.w
在把 x23
写进 x20
指向的内存位置之前,先判断 x20
指向的内存位置有没有设置保留标记,如果有,写入成功,x11
被设置为 0;如果没有,写入失败,x11
被设置为 1;无论成功与否,x20
指向的内存位置的保留标记都会被 sc
清除
在第二个例子中,x20
指向了一个锁