计算机组成原理:主存储器的组成和基本操作
计算机组成原理第三章 3.2节:主存储器的组成和基本操作
核心考点#
- 各种存储器的名称和类型
- 总容量计算
- 地址线、数据线需要多少根
- 多模块存储器(交叉存储)下的容量、寻址、带宽、给定数据地址,求 n 次存取周期才能访问到此数据
存储器芯片的原理#
地址线、数据线、片选信号、读写信号的介绍,总容量的计算,寻址方式
存储体的构成#
存储体内部由一个个存储单元(unit)构成,每一个 unit 由数个存储细胞(cell)构成,每个 cell 由 MOSS 管和电容构成,存储 1 bit 的信息(高电平代表 “1”)。而连续的 8 个 cell 同一端都接了同一根线,如果该数据线被接通,那么这 8 个 cell 都通上了电,可同时被读写。

因此,我们称这可同时被写入的位数大小为存储字长,称这一个被写入的存储单元 cell 为存储字。(字字节)
地址的选择(编码)#
进行读写时,需要存储体根据 CPU 里的 MAR 送来的 n 位地址,使用译码器对编码的地址进行翻译。因为送来的 n bit 可表示的地址范围是 ,为了还原出是要读写哪个 cell,需要译码器将编码地址翻译为对应的电信号串,控制对应的字选线为高电平,从而让 MDR 通过数据线(位线)成功将数据写入/读取。
例如 3-8 译码器,地址编码为 010,翻译为电信号串就是 控制第二根字选线为高电平,其他为低电平。(3 bit 足以表示 8 根字选线)
因此总容量等于 存储单元个数 X 存储字长 = 字选线数量 X 数据线数量
注意:
- 地址总线直接连接 CPU,MAR,译码器,通过译码器将地址翻译为 的电信号串,对应 根字选线
- 数据总线直接连接 CPU,MDR,存储单元,然后数据总线由 n 根数据线构成,数据线(位线)直接连接 cell

除了需要译码器外,同时还需要一个控制电路,确保读写时电平(数据)的稳定,避免是因为电平的抖动导致错误的读写操作和错误的数据写入。
同时引入片选线控制芯片的选择,在存储器里,往往是很多块芯片串联在一起,构成一块大的存储芯片。例如 位的存储芯片。可由 16 块 的芯片构成,通过片选信号 选择目标地址对应的芯片(令该芯片 为低电平,启动使能,其余芯片的 为高电平),再进行读写操作。
读写控制线的介绍如图。

考点:一块存储芯片一般有多少根引脚。
有些题目会给出一块集成芯片的参数,让你根据参数确定至少有芯片多少根引脚。

一般来说,芯片一定会对外露出以下引脚:
- 3V3 电源线
- GND 地线
- 片选线
- 读/写控制线 ,当然也有可能是两根线,读一根,写一根
再加上地址线和数据线。
例如一块由 的芯片构成的 的存储芯片,1 根片选线,有 3V3 电源线、GND 地线,还有一根读/写控制线 ;再加上 根地址线,以及 4 根数据线,总共 根线。
要是有 4 块芯片,那就需要两根片选线
寻址#
似乎不太重要
寻址方式有几种:
- 字节寻址
- 字寻址
- 半字寻址
- 双字寻址
在存储器中,数据是按字节进行存储的,每一个字节对应一个地址,同时对每一个字节进行编号(0,1,2…)。但存储体里也可以按照字进行编号和寻址,即根据每一个字的首地址和编号进行寻址。例如图中,每一个小格子都是一个字节,连续的四个字节是一个字;寻址时可以根据每个小格子(字节)来寻址,也可以根据每一个行(字)寻址。 接下来介绍,怎么根据字节的地址,快速转换为字的首地址。

图中一个字为 4B,即一个 unit 存储 4B 32 bit 信息。由于总容量为 1KB,那么按字节寻址下,存储体一共可划分为 1000 个单元,每个单元的大小为 1B。接下来转为按字寻址:
- 由于字长为 4 B,所以把连续的 4 个字节进行合并,看作是一个字
- 对字地址进行编码,第一个是 1…
- 要想找到对应编号的字地址,只需把十进制编号地址的二进制序列算数左移两位(相当于乘 4),如果是 8 个字节作为字长,那就左移 4 位(图中右上角)
- 例如我想要读取一号字(编号为 1 的字)的首地址,只需要把编号 1 (二进制为 0001)进行算数左移两位,得到 0100(4) ,即一号字的字地址
多模块存储器#
在现代计算机的主存储器内,显然不会是一整块大的存储体来进行存储,更多是采用多个存储体模块,也就是多根内存条对数据进行存储。
采用多根内存条存储的目的#
前文说过,在计算机对一根内存条进行存取时,存在一个存取时间 和存取周期 ,一般来说 ,因为当对存储体进行存取时,存储体恢复到原样时需要恢复时间 ,来稳定存取前后的电容电平,确保数据稳定。而 CPU 连续读取 n 个字时,假设 CPU 存取一个字的时间(总线周期)是 ,存取周期是 ,那么如果只有一根内存条,CPU 只需要 的时间就可存取一个字,剩下的 的时间都在等待(阻塞)存储体恢复到可读状态,所以 CPU 需要 的时间才能完成数据的读取。CPU 运行的速度本来就远大于存储器的访问速度,要等待这么长的时间是对 CPU 性能的浪费。
因此采用多根内存条的原因就是尽量缩减这 的时间,以减少 CPU 浪费在数据的存取上的时间;或者说,尽可能减小在 CPU 在执行存取操作后等待存储体恢复可访问状态的耗时。
假设有 个存储模块,CPU 每次访问存储体,存取一个字的耗时(也称总线周期)为 ,存取(一个字)周期为
低位交叉编址#
使用多个存储器进行数据存储时,有两种编址方式:高位编址和低位编址。
当 CPU 访问主存储体时,需要通过 MAR 访问存储体对应的地址单元。如果我们有 m 根内存条,则需要 个比特位对这 m 根内存条进行编号,告诉主存储体 CPU 想要访问哪根内存条里的数据。假设 MAR 里存储的地址是 AA BBBB CC,则高位交叉编址采用 AA,即高比特位进行编号;如果是低位交叉编址则使用 CC。
为方便称呼,我们对内存条的编号称为体号(模块号),对其余比特位称为体内地址(模块内地址)。

在明确了高位交叉和低位交叉的编址方式(体号和体内地址)后,我们来看两只编址方式下,数据(字)是怎么在这 4 个存储器内存储的。假设一个字的地址是 5 比特(一个字的数据是 5 比特)
高位编址:
由于是 4 根内存条,所以 2 比特足够。对 到 分别编号为 00 到 11,然后每根内存条内的编址都是从 000 到 111 的顺序编址。这样四根内存条的每个字的地址如图给出。对其存储地址分析,可以知道字的连续存储是:先在同一根内存条顺序存储,存满后再存下一根内存条,也就是纵向连续存储。
低位编址:
同理,对 到 分别编号为 00 到 11,然后每根内存条内的编址都是从 000 到 111 的顺序编址。但可以看到,此时字的存储是横向的,而不是高位的纵向顺序存储。例如 里存的都是 , 存的是 的地址的字。
高位编址下:
实际上观察地址,按字编址,可以看到就算使用 2 比特编码后,数据单元的地址不变,只是改变了数据的存储方式。例如低位编址的 00101 存储的仍然是第五个数据单元,存储在 的第二个地址上。
图中左侧为高位编址

在使用高位编址的情况下,我们进行连续字的存取时,CPU 会顺序读取 里的内容,所有变量如图所示,假设此时连续读取 5 个字:由于五次读取都在 里执行,每次读取时 都需要一定时间来恢复(由可知恢复时间为),而在恢复时间(冷却时间)内禁止 CPU 读取内容,所以连续访问五个字时,高位编址耗时 。

即实际上高位编址相当于存储盘扩展,只扩展容量,但没有提高 CPU 访问速率,效率仍然低下且浪费。
低位交叉编址:真正的流水线存取
图中右侧为低位编址


低位编址有一个特点:数据单元是横向存储的,或者说,连续的数据单元存储在独立、分割的 个内存条中。这样做的效果显而易见:当 CPU 连续访问多个字(例如 5 个)时,CPU 首先在 读取到第一个数据单元 000 00,然后在 读取 unit 2 000 01,在 读取 unit 3 000 10,在 读取 unit 5 000 11;而当读取 unit 5 001 00时, 正好恢复( 每个存储器的访问恢复时间是 ,而存取时间是 ),CPU 无需等待存储体恢复就可以从 读取 unit 5。
即在前面存储体的恢复时间内去访问其他可正常读取的存储体,从而极大提高了存取速率。从高位编址的 缩减为 , 是因为读取 unit 5(最后一个存储单元)时,CPU 的存取时间 加上存储体 需要 的恢复时间,这样才算完整的”CPU 读取五个数据单元所用的时间”。即第一个 完成前四个单元的存取,最后的 完成 unit 5 的存取。
可得以下信息:
采用低位交叉时,若连续存/取 个字,则耗时
当 时,字存取平均时间为 ()
推导:
实际上这是一个等差数列的通项公式求解。需要明白一点:设存取周期为 ,存取时间 ,则单根存储体 的恢复时间 。
以 为例,画图后可以知道以下表格:
| 存储字个数( n ) | 总耗时 |
|---|---|
| 3 | |
| 4 | |
| 5 | |
| n |
即通项公式 。当 时,从 开始,耗时的 ” ” 变为了 ,因此通项公式 ,可用数学归纳法验证,证毕。
轮流启动方式#
设存取时间(也叫总线传输周期)为 ,模块数(内存条数)为 m,存取周期为 T。
为了让这种流水线的存取方式不中断,即 CPU 无需等待存储器的恢复时间,应该有以下要求:
因为,T 可以表示 r 的倍数(不一定是整数),如上例的 ,而 比它们的比值大时,CPU 才无需等待存储器恢复,可直接、连续、不间断地读取主存里的内容。

存取时间和线传输周期是两种描述,但都指的是 CPU 访问主存中一个字所用的时间
如何确认给定地址的字属于哪个存储体#
以低位编址为例:
-
如果给出二进制串,查看地址的低位()
-
转为十进制即可
-
如果给出十进制地址 x,直接取余 m:
芯片扩展与同时启动方式#
若干存储器芯片可构成一个内存条,此时,需要在字方向和位方向上进行扩展。
位扩展:用若干位数较少的存储器芯构成给定字长的内存条时,需要进位扩展。例如,用 片 位的芯片构成 位的内存条,需要在位方向上扩展 倍,而字方向上无须扩展。因此数据线从 根扩展为 根。
字扩展:子扩展是容量的扩充,位数不变。例如,用 位的存储芯在字方向上扩展 倍,可构成一个 位的内存条。地址线从 根扩展为 根。
当芯片在容量和位数都不满足存储器要求的情况下,需要对字和位同时扩展。例如,用 位的存储芯片在字方向上扩展 倍、位方向上扩展 倍,可构成一个 位的内存条。
下图给出了用 个 位的 DRAM 芯片扩展构成一个 内存条的示意图。DRAM 芯片中有一个 位的存储阵列,行地址和列地址各 位,有 个位平面。

每一颗 DRAM 芯片都是 位,图中每一颗 DRAM 是平面结构,省略了“厚度”的描绘,即 DRAM 芯片为:长 , 高 ,宽 比特。
内存条通过存储器总线连接到存储控制器(简称存控),CPU 通过存控对内存条中的 DRAM 芯片进行读写。存控会将 CPU 送出的主存地址转换为地址 和列地址 ,它们被分时送到 DRAM 芯 片中的行地址译码器和列地址译码器,以选择行、列交叉处的 位数据同时进读/写,因此一个芯每次读/写 位。 个芯片就可同时读取 位,组合成总线所需要的 位传输宽度。
现代通用计算机大多按字节编址,因此,在图 7.10 所示的存储器结构中,同时读出的 位只可能是第 单元,第 单元,第 单元,以此类推。
因此,如果访问的一个 int 型数据不对齐,例如,起始地址为 ,即在第 、、、 这 个存储单元中,则需要访问两次存储器:因为字节 位于 DRAM 0, 位于 DRAM 1,CPU 需要先使用 MDR 存储 DRAM0 对应的单元 unit 地址,访问 DRAM 0,再进行相同的操作访问 DRAM 1,才能获取到完整的 int 数据。如果数据对齐的话,即起始地址是 的倍数,例如 ,或 ,则只要访问一次即可。这就是内存访问要求数据对齐的根本原因。
同时启动方式:
如果所有存储模块一次并行读写的总位数正好等于存储器总线中数据位数,则可用同时启动方式。例如,对于图 7.10 所示的内存条,每个存储模块(即每个 DRAM 芯片)提供 位数据, 个 DRAM 芯片一共提供 位数据,正好构成一个总线传输单位,因此,可同时启 动 个芯进并读写,同时读写 位数据。
现代计算机中由于在 CPU 和主存之间设置有告诉缓存(cache),因而通常 CPU 是对一个主存块中的连续单元进访问,DMA 传送也是将一块连续主存单元与速设备进数据交换,因此,对主存的访问通常都是读写一块连续的主存单元。对于连续一块信息的读写,采用(低位)交叉编址的多模块存储器,通过轮流或并行访问多个存储模块,可以显著提高访存速度。