多模块存储器的基本思想

多模块存储器(Multi-Module Memory) 将存储器组织为多个可以独立进行存取的模块,让不同模块的访问过程重叠,从而提高整体吞吐量与带宽。

可以把它理解成银行的多个业务窗口:每个窗口办理一位客户所需的时间没有改变,但多个窗口同时工作,单位时间内就能服务更多客户。

假设共有 16 个存储单元,将其分为 4 个模块 M0~M3,每个模块保存 4 个单元。接下来要解决两个问题:

  • 怎样分配地址? 决定连续访问会落在哪些模块。
  • 怎样安排访问? 决定能否利用不同模块的并行能力。

重点: 多模块的主要作用是提高存储器带宽(Memory Bandwidth),即单位时间内传输的数据量;单次访问延迟(Access Latency)不一定缩短。

高位交叉与低位交叉编址

交叉编址(Interleaved Addressing) 通过地址中的不同位选择模块,主要有高位交叉和低位交叉两种方式。

以下都以 16 个存储单元、4 个模块为例:地址共 4 位,每个模块有 4 个单元,因此模块号和模块内地址各需要 2 位。

高位交叉编址

高位交叉编址(High-Order Interleaving) 用地址高位选择模块,低位确定模块内部的位置。

地址:A3 A2 | A1 A0
       ↓       ↓
     模块号  模块内地址

地址按连续区域分配给各模块:

模块 所包含的地址
M0 0、1、2、3
M1 4、5、6、7
M2 8、9、10、11
M3 12、13、14、15

例如,地址 13 的二进制表示为 11|01,因此位于 M3,模块内地址为 1。

连续访问 0 → 1 → 2 → 3 时,四次访问都落在 M0,必须遵守同一模块的存取周期,其他模块无法分担这组请求。

特点: 每个模块对应一个连续地址区间,便于组织容量扩展;连续访问通常集中在同一模块,只有访问分布到不同模块时,才能利用模块间的并行能力。

低位交叉编址

低位交叉编址(Low-Order Interleaving) 用地址低位选择模块,高位确定模块内部的位置。

地址:A3 A2 | A1 A0
       ↓       ↓
   模块内地址  模块号

连续地址轮流分配到不同模块:

模块内地址 M0 中的地址 M1 中的地址 M2 中的地址 M3 中的地址
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
3 12 13 14 15

因此,连续访问对应的模块为:

地址:0  1  2  3  4  5  6  7
模块:M0 M1 M2 M3 M0 M1 M2 M3

若地址为 AA,模块数为 mm,则低位交叉的地址映射为:

模块号=A mod m,模块内地址=⌊Am⌋.\begin{aligned} \text{模块号} &= A\bmod m,\\ \text{模块内地址} &= \left\lfloor\frac{A}{m}\right\rfloor. \end{aligned}

例如,地址 13 的二进制表示为 11|01,低 2 位 01 选择 M1,高 2 位 11 表示模块内地址 3。用公式计算也得到:13 mod 4=113\bmod4=1,⌊13/4⌋=3\lfloor13/4\rfloor=3。

当 m=2km=2^k 时,模块号就是地址的最低 kk 位。

特点: 连续地址分散在不同模块,适合让多个模块轮流启动、重叠工作,充分利用连续访问的并行性。

两种编址方式的对比

对比项 高位交叉 低位交叉
模块选择 地址高位 地址低位
模块内地址 地址低位 地址高位
地址分布 每个模块保存一段连续地址 连续地址轮流分配到不同模块
连续访问的并行利用 同一地址区间内通常访问同一模块 连续访问可在多个模块间交错进行
常见目的 组织连续地址区域、扩展容量 提高连续访问的带宽

两种方式都能使用多个模块。区别在于哪些地址会落入同一模块,并非高位交叉的模块本身不能并行工作。

低位交叉怎样提高带宽

区分访问延迟与存取周期

  • 访问延迟(Access Latency):从发起请求到取得数据所需的时间。
  • 存取周期(Memory Cycle Time):同一模块连续启动两次存取所需的最小时间间隔。
  • 吞吐量(Throughput):单位时间完成的访问次数。
  • 带宽(Bandwidth):单位时间传输的数据量,还与每次传输的数据宽度有关。

多模块交叉访问利用的是:一个模块忙于当前访问时,可以启动另一个模块的访问。 这类似流水线(Pipelining),不同请求的处理过程在时间上重叠。

4 个模块的访问时序示例

沿用低位交叉的地址分配。为便于示意,假设每个模块的访问延迟与存取周期都为 100 ns,控制器和总线允许每 25 ns 启动一次访问,忽略额外传输开销。

若只有一个模块,连续读取 4 个字,需要依次启动:

读取地址 启动时刻 数据就绪时刻
0 0 ns 100 ns
1 100 ns 200 ns
2 200 ns 300 ns
3 300 ns 400 ns

采用 4 个模块低位交叉时,可错开启动:

读取地址 访问模块 启动时刻 数据就绪时刻
0 M0 0 ns 100 ns
1 M1 25 ns 125 ns
2 M2 50 ns 150 ns
3 M3 75 ns 175 ns
4 M0 100 ns 200 ns

M0 在 0 ns 启动第一次访问,下一次访问 M0 已经是 100 ns,恰好满足其存取周期。其他模块也按同样的节奏循环工作。

前 4 个字分别在 100、125、150、175 ns 就绪,最后一个字在 175 ns 就绪,而单模块需要到 400 ns。进入稳定状态后,系统可每 25 ns 提供一个字,但每次访问本身仍需要 100 ns。

对应的理想访问吞吐量为:

  • 单模块:1/(100 ns)=1071/(100\text{ ns})=10^7 次/秒。
  • 四模块交叉:1/(25 ns)=4×1071/(25\text{ ns})=4\times10^7 次/秒。

若每次传输的数据量相同,则这一理想模型下,稳定状态的带宽提高为原来的 4 倍。

并行收益需要什么条件

要连续按上述节奏访问,返回同一模块时,它必须已能接受下一次请求。若模块数为 mm、存取周期为 TT、请求启动间隔为 τ\tau,则需要满足 mτ≥Tm\tau\ge T。

实际收益还取决于请求分布、控制器和总线能力。例如,虽然采用低位交叉,但若访问地址为 0 → 4 → 8 → 12,请求仍全部落在 M0,产生模块冲突(Bank Conflict),就无法取得上述连续地址访问的收益。

重点: 低位交叉让连续地址分散到不同模块;交错启动让不同模块的访问重叠。两者配合提高吞吐量和带宽,而不是改变单个模块本身的速度。

实际系统中的类似思想

DRAM 的多 Bank 结构

DRAM 芯片内部划分为多个 Bank(存储体),存储控制器(Memory Controller)可以让不同 Bank 的内部操作交错进行。

例如,一个 Bank 正在处理访问时,另一个 Bank 可以准备后续访问。这样能利用操作重叠提高整体吞吐量;若多个 Bank 共用数据通道,数据输出仍须按接口能力安排。

这与多模块交叉存储的基本思想相通,但现代 DRAM 的地址映射和访问时序更复杂,不一定直接采用教材中的简单取模映射。

SSD 的多通道结构

固态硬盘(Solid-State Drive,SSD)内部包含多个 NAND 闪存芯片(NAND Flash)和通道(Channel),控制器可以在不同通道上并行安排读写。

SSD 控制器
     │
     ├── 通道 0 → NAND Flash
     ├── 通道 1 → NAND Flash
     ├── 通道 2 → NAND Flash
     └── 通道 3 → NAND Flash

它与教材中的多模块主存结构并不完全相同,但都体现了将请求分散到多个独立资源,通过并行或重叠工作提高吞吐量的思想。