一、核心结论
对于采用低位交叉编址的多体存储器,要达到理论上最高的连续读写带宽,其存储模块的数量 M 必须等于主存访问周期 T 与总线传输周期 τ 之比。
即:
这个公式是理想情况下的要求。它的目标是:当 CPU 连续访问主存时,能够在每个总线传输周期 τ 内,都有一个存储模块准备好数据,供 CPU 访问,从而消除等待时间,实现流水线式的数据传输。
二、为什么有这个要求?(工作原理详解)
1. 定义关键参数
- T(主存访问周期):启动一个存储模块到完成数据读写所需的完整时间。
- τ(总线传输周期):CPU 通过系统总线从存储模块接收或发送一个数据字所需的时间。
- M(存储模块数量):采用低位交叉编址的存储体的总数。
2. 目标:流水线操作
希望实现每隔时间 τ,就有一个存储体把数据准备好送到总线上,形成连续的流水线访问。
3. 时序分析
最理想的流水线时序安排: - 在 t=0 时刻启动模块 0 - 在 t=τ 时刻启动模块 1 - 在 t=2τ 时刻启动模块 2 - … - 在 t=(M-1)τ 时刻启动模块 M-1
为了保证流水线不断流,当启动完最后一个模块后,第一个模块应该刚好结束忙碌状态: 最理想的情况是: 因此:
三、代码示例:时序模拟
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| def simulate_low_order_interleaving(T, tau, sequence_length): 模拟低位交叉多体存储器的访问时序 """ 参数: T: 存储模块访问周期 tau: 总线传输周期 sequence_length: 连续访问的地址数量 """ M = int(round(T / tau)) # 计算最优模块数量 print(f"存储模块访问周期 T = {T}") print(f"总线传输周期 τ = {tau}") print(f"最优存储模块数量 M = T/τ = {M}") print(f"预计带宽提升: {M}倍") print("\n访问时序模拟:") # 模拟访问时序 for i in range(min(sequence_length, 10)): # 只显示前10次访问 module_id = i % M start_time = (i // M) * T + (i % M) * tau ready_time = start_time + T print(f"访问 {i:2d} -> 模块 {module_id}: " f"启动时间 t={start_time:4.1f}, " f"就绪时间 t={ready_time:4.1f}")
# 示例参数 T = 100 # 存储周期100ns tau = 20 # 总线周期20ns simulate_low_order_interleaving(T, tau, 12)
|
输出示例:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 存储模块访问周期 T = 100 总线传输周期 τ = 20 最优存储模块数量 M = T/τ = 5 预计带宽提升: 5倍
访问时序模拟: 访问 0 -> 模块 0: 启动时间 t= 0.0, 就绪时间 t=100.0 访问 1 -> 模块 1: 启动时间 t=20.0, 就绪时间 t=120.0 访问 2 -> 模块 2: 启动时间 t=40.0, 就绪时间 t=140.0 访问 3 -> 模块 3: 启动时间 t=60.0, 就绪时间 t=160.0 访问 4 -> 模块 4: 启动时间 t=80.0, 就绪时间 t=180.0 访问 5 -> 模块 0: 启动时间 t=100.0, 就绪时间 t=200.0
|
四、不同情况对比
| 场景 | 数量关系 | 性能表现 | 说明 |
|---|
| 理想情况 | M = T/τ | 带宽最大 | 完美流水线,每个τ周期都有数据 |
| 模块不足 | M < T/τ | 带宽受限 | 存在等待周期,无法充分利用带宽 |
| 模块过多 | M > T/τ | 带宽饱和 | 额外模块在连续访问中无法带来增益 |
五、重要注意事项
- 实际取值: M 应该取不小于 T/τ 的最小整数
- 地址映射: 低位交叉使用地址的低位选择模块,高位选择模块内地址
- 应用场景: 主要优化连续地址访问模式,对随机访问效果有限
- 工程权衡: 需在性能提升和硬件成本之间取得平衡