Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

更大的存储

复习

  1. 第二十六章:设计实现了寄存器,本质是多个触发器并排连接
  2. 第二十七章:把寄存器接入回路,做出了能自动累加的累加器
  3. 第二十八章:了解了时序逻辑,知道它靠存储元件保存状态

TL;DR

  • 想要更大存储,最直接的办法是把很多寄存器并排连起来
  • 但并排的线会随容量爆炸式增长
  • 解决办法:给每个存储单元编号(地址),用地址译码器按需选中,再把单元排成矩阵

正文

引言

  第二十六章里,我们用一排触发器做出了寄存器,能存 8 位、16 位或 32 位数据。可这远远不够用——现在随便一个文件就有一两 MB(忘了 MB 是什么?回第四章看看)。

  想要更大的存储,怎么办呢?

先试试最直接的办法

  最容易想到的办法:把所有寄存器并排连在一起。大概长这样:

  看起来没问题,只是线有点多。多到什么程度呢?以 8 位寄存器为例:

  • 8 根数据输入线
  • 8 根数据输出线
  • 1 根写入控制线

  一共 17 根。如果要存 1000 个 8 位数据,就是 17000 根线。晶体管才不在乎多几个,但芯片上的引脚和走线是极其宝贵的资源,这么多线根本排不下。这就是这种办法最大的问题——线太多了。

换个角度想

  为什么我们觉得“每个寄存器都要有独立的输入输出线“?因为我们默认:任何时候都要能同时读写所有数据。

  可实际使用中,我们绝大多数时候只需要读写其中一个数据。比如查数组的某个元素、取一条指令,都只关心某一块,而不是全部。

  既然如此,何必给每个人都修一条专用通道?修一条公共通道,再给每个存储单元发一个门牌号,需要谁就叫谁出来不就行了?

地址与译码器

  这个“门牌号“,就叫地址(Address)。存放数据的每一个小格子,叫一个存储单元

  于是电路的形态变成了:

  • 所有存储单元共享一组数据线
  • 每个单元有自己的地址
  • 想读/写谁,就把谁的地址送上地址线
  • 用一个地址译码器,把地址翻译成“选中某某单元“的控制信号

  译码器我们在第十八章造 ALU 时已经见过:它把一串二进制码,翻译成“选中其中一根线“的信号。比如 2 位地址能区分 4 个单元,3 位能区分 8 个。

排成矩阵

  光有地址还不够。如果只并排成一长排,走线依然很长。工程师们的办法是排成二维矩阵

  • 把单元摆成若干行、若干列
  • 地址分成两部分,分别选中“第几行“和“第几列“
  • 行列交叉处的那一个单元才被激活

  这样一来,n 个单元只需要大约 √n 行 + √n 列的控制线,线数量大大减少。这和“图书馆用楼层+书架号定位一本书,比给每本书编一个长编号再一字排开“是一个思路。

  有了地址、译码器和矩阵,一个能存放大量数据、又能按需取用的部件就成型了。它有一个我们熟悉的名字——存储器(Memory)。下一章我们就专门来看它。

思考题

  并排连接的方式线太多,矩阵方式省线。那为什么寄存器不干脆也排成矩阵、共用数据线,省下那些线?提示:想想寄存器最大的特点是什么。

小结

知识点

  • 并排寄存器的“线爆炸“问题
  • 地址与存储单元
  • 地址译码器
  • 存储矩阵

参考资料

  1. Wikipedia(zh):地址译码器:地址译码的基本原理
  2. Wikipedia(zh):存储器:存储器的一般概念
  3. 《编码:隐匿在计算机软硬件背后的语言》第 16 章:存储器

思考题答案(仅供参考)

  寄存器最大的特点是,而且是“随取随用“。CPU 每个时钟周期都可能同时用到好几个寄存器(比如两个操作数加一个结果),所以它必须让所有寄存器都能被并行、直接地访问,这正是靠“每人一条专用线“换来的。存储器要的是容量大、成本低,牺牲一点速度、改成“按地址一个一个取“完全值得。速度和容量,本来就是一对矛盾,这正是存储层次结构要解决的问题。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪