Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions W10D1-Notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Tomasulo
## Background

Tomasulo算法是为了解决传统五级流水线中存在的结构冲突、数据冲突和控制冲突等问题而提出的。五级流水线虽然提高了指令的并行度,但在面临数据相关性和流水线阻塞时,性能受到了限制。Tomasulo算法的提出旨在克服这些局限,通过动态调度和乱序执行的方式提高指令的并行度,以进一步提高处理器的性能。

## Rename

Tomasulo算法引入了重命名寄存器(Register Renaming)和保留站(Reservation Stations)的概念,以解决数据冲突。通过使用重命名寄存器,指令不再直接使用物理寄存器,而是使用保留站中的标记(tag)来标识数据。这样,即使多条指令需要访问相同的物理寄存器,也不会产生数据冲突。保留站中的数据来源可以是寄存器、内存或其他保留站的输出。

## 执行流程

Tomasulo算法的执行流程主要包括以下步骤:

1. **发射(Issue):** 指令从指令缓存进入执行阶段。在发射阶段,指令被分配到可用的保留站,并为其分配重命名寄存器。如果保留站不可用,指令将等待直到有可用的保留站。

2. **执行(Execute):** 一旦指令的操作数就绪,它就会进入执行阶段。在执行阶段,指令使用重命名的寄存器执行运算,并将结果存储在保留站中。

3. **写回(Write Back):** 一旦指令的执行完成,结果将被写回到保留站中。其他等待该结果的指令将得到通知,表明数据已经就绪。

4. **提交(Commit):** 当指令的结果被写回到重命名寄存器中,该指令被标记为已提交。这时,结果被传送到物理寄存器文件,以供后续指令使用。

通过这种方式,Tomasulo算法实现了乱序执行和动态调度,使得处理器能够更好地处理数据相关性,提高指令级并行度,从而进一步提高计算机系统的性能。
47 changes: 47 additions & 0 deletions W14D1-Notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# W14D1笔记 —— Review

## Pipeline

### Hazard

#### 1. 结构冒险(Structural Hazard)

**定义:** 结构冒险发生在硬件资源的冲突上,即多个指令同时需要访问相同的硬件模块,但硬件无法同时服务它们。

**示例:** 在单一存储器模块的体系结构中,同时进行取指令(Instruction Fetch)和写回操作(Write Back)可能导致结构冒险。

**解决方法:** 增加硬件资源,例如多个数据通路或多个存储器模块,以避免资源的竞争。

#### 2. 数据冒险(Data Hazard)

**定义:** 数据冒险发生在程序中的指令之间存在数据依赖关系,导致某些指令需要等待前面的指令完成才能执行。

**示例:**
- **读后写数据冒险(Read After Write Dependency):** 指令 A 写回的结果是指令 B 读取的操作数,但指令 B 在指令 A 写回前执行。
- **写后写数据冒险(Write After Write Dependency):** 多个指令试图同时写入相同的目标,导致其中一个指令的写入结果被覆盖。

**解决方法:**
- 使用数据前推(Data Forwarding)或旁路技术,将写回的结果直接传递给等待的指令。
- 插入流水线暂停或空闲周期,使相关的指令能够正确执行。

#### 3. 控制冒险(Control Hazard)

**定义:** 控制冒险发生在程序的控制流发生改变,例如分支或跳转指令导致了不确定的下一条指令。

**示例:**
- **分支冒险(Branch Hazard):** 当一个分支指令的条件判断结果确定后,需要选择正确的分支目标,而之前的指令已经进入流水线,可能导致错误的分支目标的指令被执行。

**解决方法:**
- 使用预测技术,例如分支预测(Branch Prediction),通过猜测分支的方向来提前执行下一条指令。
- 在分支预测失败时,使用流水线刷新或插入无效指令来纠正控制流。
### 乱序

* 问题: 精准中断,跳转
* 解决: ROB保证提交顺序
* Tomasulo: Issue -> execute -> commit

### Cache & Memory

$AMAT_{cache} = T_{hit} +\eta_{miss-rate}*T_{penalty}$

$AMAT_{mem} = T_{addr} +T_{access}+T_{trans}$
41 changes: 41 additions & 0 deletions W6D1-Notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Cache

## 为何需要引入缓存?

在计算机体系结构中引入缓存的主要目的是提高程序的执行速度和系统的整体性能。传统的存储器(如RAM)速度较慢,而CPU执行速度较快,因此为了减少CPU等待数据的时间,引入缓存是一种有效的策略。缓存通过存储最常用的数据和指令,以降低访问主存的频率,从而提高程序的执行效率。

## 什么是缓存?

缓存是一种小而快速的存储设备,用于暂时存储经常访问的数据和指令。它位于CPU和主存之间,起到缓冲的作用,使得CPU能够更快地获取所需的数据,而无需每次都直接访问主存。

## 哈佛架构和冯诺伊曼架构

- **哈佛架构(Harvard Architecture):** 哈佛架构将数据存储和指令存储分开,分别使用独立的存储单元。这样的架构使得同时进行指令和数据访问成为可能,提高了系统的并行性。

- **冯诺伊曼架构(Von Neumann Architecture):** 冯诺伊曼架构将指令和数据存储在同一存储器中,共享同一地址空间。这是传统计算机体系结构的典型范例,简化了系统设计但限制了并行性。

## 如何提升缓存性能?

提升缓存性能的方法包括:

- **增加缓存容量:** 更大的缓存可以存储更多的数据,提高命中率,从而减少对主存的访问次数。

- **提高缓存关联性:** 关联性指的是缓存中一组数据映射到的位置。增加关联性可以减少缓存替换带来的性能损失。

- **使用更快的缓存技术:** 使用更快速、更高效的缓存技术,如高速缓存(SRAM)替代低速缓存(DRAM)。

- **采用多级缓存:** 使用多级缓存,分为L1、L2等级别,以提高系统整体的性能。

## 缓存未命中的原因和解决方案

缓存未命中可能由以下原因引起:

- **冷启动(Cold Start):** 系统启动时,缓存为空,需要一段时间才能达到稳定的命中率。解决方法是采用预取技术,在程序运行前将一部分数据预先加载到缓存中。

- **容量未命中(Capacity Miss):** 缓存无法容纳全部所需的数据,导致部分数据被替换出去。解决方法包括增加缓存容量、改进替换算法等。

- **冲突未命中(Conflict Miss):** 多个数据映射到相同的缓存位置,导致替换。提高关联性或使用更复杂的映射方式可以缓解这种未命中。

- **失效未命中(Compulsory Miss):** 第一次访问的数据导致未命中。预取、更大的缓存或更快的访问方式可以减少这种未命中。

通过这些方法,可以改善缓存性能,提高系统整体的执行效率。