跳转至

Chapter 1

第一章讲的太零散了,有用的知识点感觉就是

  • 八个伟大思想(cs61c好像只取了6个)

  • 衡量计算机性能表现的指标

1 Eight Great Ideas

设计紧跟摩尔定律 (Design for Moore’s Law)

  • 核心逻辑:由于计算机设计周期可能长达 3-5 年,而芯片性能每 18-24 个月翻倍。如果你按“现在的技术”设计,发布时它就已经落后了。
  • 举例:如果你在 2024 年设计一款 2027 年上市的 3A 游戏,你不能按现在的显卡内存(如 8GB)来定上限,你必须假设 2027 年的主流配置是 16GB 甚至更高,提前留出冗余。

2. 采用抽象简化设计 (Use Abstraction to Simplify Design)

  • 核心逻辑:硬件极其复杂(数亿个晶体管),没人能全盘掌握。于是我们把系统分层:指令集(ISA)是软件和硬件之间的“合同”,软件不需要知道晶体管怎么排布。
  • 举例驾驶汽车。你只需要知道方向盘、油门和刹车(这是抽象层),而不需要知道发动机气缸是如何点火的。这种抽象让你能驾驶不同品牌的汽车。

3. 加速大概率事件 (Make the Common Case Fast)

  • 核心逻辑:优化那些占执行时间 90% 的指令,比优化那些只占 1% 的指令收益高得多。这就是著名的 Amdahl's Law
  • 举例超市收银。大多数人买东西很少,所以超市设置“10 件以下小额快速通道”。这优化了大部分消费者的体验,而不是为了偶尔出现的“推三车货的大户”去设计所有通道。

4. 通过并行提高性能 (Performance via Parallelism)

  • 核心逻辑:一个人干活慢,那就找一群人一起干。
  • 举例建筑工地。如果只有一个人盖房子,要先打地基、砌砖、装水电。如果一群人并行工作,有人负责打地基的同时,另一边可能在预制墙体,速度倍增。在 CPU 中,多核(Multi-core)就是典型的并行。

5. 通过流水线提高性能 (Performance via Pipelining)

  • 核心逻辑:把任务拆成若干步骤,每个步骤由专门的人负责。
  • 举例自动洗车房
  • 第一辆车在冲水时,第二辆车还没进场;
  • 当第一辆车在打泡沫时,第二辆车已经在冲水了。 虽然每辆车洗完总时长没变,但平均每分钟“出厂”的干净车变多了。你提到的“时间均匀”很重要,否则会出现“交通堵塞”。

6. 通过预测提高性能 (Performance via Prediction)

  • 核心逻辑:与其原地等待某个结果(如 if 判断),不如猜一个结果先做下去。猜对了节省时间,猜错了回滚,损失也不大。
  • 举例餐厅排队。如果厨师预感到接下来 10 分钟会有很多人点“宫保鸡丁”,他会提前切好原料甚至炒好几份。如果猜对了,顾客拿菜即走;如果猜错了,大不了把这几盘菜倒掉(成本可控)。

7. 存储器层次 (Hierarchy of Memories)

  • 核心逻辑:我们想要“速度极快、容量极大、价格极低”的内存,但这在物理上不可能。于是我们用“金字塔”结构:最快但最贵的放在最顶层(寄存器),最慢但最便宜的放在底层。
  • 举例程序员的书桌
  • 寄存器:你的手心(抓着笔)。
  • L1-Cache:桌面上摊开的书(随手就翻)。
  • 主存:身后的书架(得站起来拿)。
  • 磁盘:市中心的图书馆(得开车去,极慢但存得下全世界的书)。
  • memory hierarchy pyramid的图片Shutterstock

8. 通过冗余提高可靠性 (Dependability via Redundancy)

  • 核心逻辑:硬件总会坏。为了让系统不停机,我们需要备用方案。
  • 举例飞机的发动机。大型客机通常至少有两个发动机。如果飞行中一个坏了,另一个足以支撑飞机安全降落。在计算机中,RAID 磁盘阵列就是把一份数据存两份,坏了一块盘,数据也不丢。

这八大思想是贯穿整本《计算机组成与设计》教材的。当你以后学到“Cache 设计”时,你会发现它运用了存储器层次加速大概率事件;当你学到“分支预测器”时,它就是在实践通过预测提高性能


2 性能指标

1. 响应时间和吞吐量

这两个指标虽然都衡量“速度”,但视角完全不同:

响应时间 (Response Time / Execution Time)

  • 定义:从任务提交到任务完成的总耗时。
  • 关注点“单个任务跑得有多快?”
  • 组成:包括磁盘访问、内存访问、I/O 活动、操作系统开销以及 CPU 执行时间。
  • 适用人群:普通个人电脑用户。比如你打开一个 Photoshop 滤镜,你只关心它几秒能处理完。

吞吐量 (Throughput / Bandwidth)

  • 定义:在单位时间内完成的总工作量。
  • 关注点“单位时间内能处理多少任务?”
  • 适用人群:服务器管理员或数据中心。比如一个 Web 服务器,管理员关心的是每秒能处理多少个 HTTP 请求,而不是某一个特定请求的延迟。

Tip

想象一条高速公路。

  • 响应时间:是一辆车从 A 点开到 B 点所需的时间。

  • 吞吐量:是单位时间内通过收费站的车辆总数。

增加车道的宽度可以提高吞吐量,但不一定能缩短单辆车的行驶时间(响应时间)。


性能与执行时间的关系

在计算机科学中,性能(Performance)与执行时间(Execution Time)成反比关系。其公式表达为:

\[\text{Performance}_x = \frac{1}{\text{Execution Time}_x}\]

这意味着:

  • 执行时间越,性能越
  • 如果执行时间缩短为原来的 \(\frac{1}{2}\),那么性能就提升了 \(2\) 倍。

相对性能 (Relative Performance)

当我们说“机器 A 比机器 B 快 n 倍”时,我们就是在计算相对性能。

如果我们要比较 A 和 B 的性能,公式如下:

\[\frac{\text{Performance}_A}{\text{Performance}_B} = \frac{\text{Execution Time}_B}{\text{Execution Time}_A} = n\]

如何解读结果 \(n\)

  • 如果 \(n > 1\),说明 A 的性能优于 B。
  • 例题:程序在电脑 A 上运行需要 10s,在电脑 B 上需要 15s。
\[\frac{\text{Performance}_A}{\text{Performance}_B} = \frac{15s}{10s} = 1.5\]
  • 结论:电脑 A 的性能是电脑 B 的 1.5 倍,或者说 A 比 B 快 50%。

2. CPU 执行时间 (CPU Execution Time)

这是最真实、最本质的指标。它指的是 CPU 真正花在运行某程序指令上的时间,不包括等待 I/O 或运行其他程序的时间。


3. 时钟周期 (Clock Cycle)

计算机的操作是由时钟控制的。时钟周期是计算机中最小的时间单位(就像心跳)。

  • Clock Cycle Time (\(C\)): 一个时钟周期的长度(例如 \(0.25ns\))。
  • Clock Rate (\(R\)): 时钟频率,即单位时间内有多少个周期(例如 \(4GHz\))。
  • 关系:\(Clock Cycle Time = \frac{1}{Clock Rate}\)

4. 性能方程

时间 = 周期总数 × 周期长度

这是最直观的逻辑:

\[\text{CPU Time} = \text{CPU Clock Cycles} \times \text{Clock Cycle Time}\]

或者写成频率的形式:

\[\text{CPU Time} = \frac{\text{CPU Clock Cycles}}{\text{Clock Rate}}\]

我们知道 CPU 运行程序是因为它执行了一系列指令。但并不是每条指令耗时都一样(比如“加法”可能只需 1 个周期,而“除法”可能需要 20 个)。

因此,我们引入 CPI (Cycles Per Instruction):

\[\text{CPI} = \frac{\text{CPU Clock Cycles}}{\text{Instruction Count}}\]

将上述关系整合,就得到了:

\[\text{CPU Time} = \text{Instruction Count} \times \text{CPI} \times \text{Clock Cycle Time}\]

它把计算机性能拆解成了三个互不相同但又互相制约的维度:

指标 影响因素 谁负责优化?
Instruction Count (IC) 算法、程序设计语言、编译器、指令集(ISA) 软件工程师、编译器专家
CPI 指令集(ISA)、微架构(Microarchitecture) CPU 设计师(流水线、缓存等)
Clock Cycle Time 硬件实现、物理电路、半导体工艺 硬件工程师、工艺厂商(台积电/Intel)

Note

一个直观的例子

假设你要对比两个处理器运行同一个程序:

  • 处理器 A:周期时间 \(250ps\),CPI 为 \(2.0\)
  • 处理器 B:周期时间 \(500ps\),CPI 为 \(1.2\)

哪个更快?(假设指令数 \(I\) 相同)

  • \(\text{Time}_A = I \times 2.0 \times 250ps = 500 \times I\ ps\)
  • \(\text{Time}_B = I \times 1.2 \times 500ps = 600 \times I\ ps\)

结论:尽管 A 的 CPI 更高(单条指令平均周期多),但由于它的时钟频率极快(周期时间短),最终 A 还是比 B 快。


在实际复杂的程序中,不同种类的指令(加法、跳转、访存)出现的频率不同。所以 CPI 通常是一个加权平均值:

\[\text{Average CPI} = \sum_{i=1}^{n} (\text{CPI}_i \times \frac{\text{Instruction Count}_i}{\text{Instruction Count}_{total}})\]

评论