# What every programmer should know about memory，Part 1
Date: 2021-10-16


这篇文章  [What every programmer should know about memory, Part 1](https://lwn.net/Articles/250967/)

是出自lwn.net 作者 Ulrich Drepper

 

#### **总线结构**

常见的商用计算机结构：

- 北桥南桥结构：

CPU通过FSB连接到北桥， 北桥包含内存控制器，通过不同内存控制器链接不同的RAM，如DRAM，SDRAM， Rambus，南桥主要连接I/O设备，支持不同总线接口如：PCI，SATA，USB。

![](https://garlicspace.com/wp-content/uploads/2021/09/cpumemory.4.png)

特点：

- cpu到cpu之间数据要过北桥
- 所有设备与RAM需要通过北桥
- RAM仅一个端口
- 通过南桥链接设备与cpu通讯需要经过北桥

瓶颈； 北桥处理能力成为瓶颈。

- 设备与内存：
- 北桥与内存

> 早些年设备间通讯需要通过cpu， 为了减少CPU压力，出现DMA，虽然减少cpu压力，但是占用北桥带宽。

为了增强北桥内存访问能力，有些系统支持北桥连接外部更多的内存控制器：

- 北桥连接外部内存控制器南北桥结构

 

![](https://garlicspace.com/wp-content/uploads/2021/09/cpumemory.5.png)

特点：

- 增强北桥处理能力

瓶颈：

- 内部带宽

> 北桥成为中心关键节点，内存控制器接入越多

另外一种解决方法是将外部控制器集成到CPU中（ NUMA）

![](https://garlicspace.com/wp-content/uploads/2021/09/cpumemory.6.png)将内存控制器集成到cpu中，不同cpu连接不同内存， 没有北桥瓶颈，但当访问链接到其他CPU的内存时使得访问变得复杂。

NUMA - Non-Uniform Memory Architecture

 

#### **RAM类型**

**Static RAM**

- 需要多个晶体管，文章中提到有6个或4个的。
- 单元状态稳定，不需要刷新周期。
- 断电后数据丢失

**Dynamic RAM**

- 需要一个晶体管和一个电容
- 需要刷新不断刷新

**DRAM 访问**

![](https://garlicspace.com/wp-content/uploads/2021/09/cpumemory.9.png)

如果要访问一个4G地址， 4GB的RAM需要2^32个地址线， 使用二进制编码，_N_ 个地址线可以完成 2_N_ 个地址，使用N个地址线，除了电路设计复杂之外需要大量的芯片，DRAM设计时使用矩阵方式，将一维的操作转化为二维操作。使用行地址选择器和列地址选择器方式。简化了电路的设计。仅需要很少地址线，为了能区分行或列需要额外的一些lines。

总结：

- 处于成本考虑内存大多使用DRAM
- 需要单独选择存储单元才能使用
- 由于性价比考虑选择DRAM地址线设计使用矩阵方式。
- 在读取或写入操作的可用之前由于电器特性需要一段时间

 

#### **DRAM 存取技术细节**

> 文中以SDRAM为例子进行介绍，SDRAM （Synchronus DRAM）对应的有 asynchronous DRAM ，主要区别就是是否使用系统时钟协调内存访问， 在异步DRAM中，没有CLK部分的设计。

**读协议**

![](https://garlicspace.com/wp-content/uploads/2021/10/cpumemory.10.png)

图中主要包含以下部分：

- 总线信号 CLK，CLK上升沿数据可读
- RAS行信号，行地址
- CAS为列信号，列地址
- Address地址总线
- DQ为数据总线

 

读取大致流程如下：

1）内存控制器将地址总线上发送行地址，并将RAS设置为低电平，读周期开始；

2）经过RCD延时后，地址总线上发送列地址，并将CAS设置为低电平；

3）经过CL延时后，准备工作就绪进行数据传输。

完成一次地址选择如果仅传送一个数据，显然有些浪费，可以看到图中进行了多个数据传输， 虽然每个周期之传输了一个字

> 为了提高效率，可以保持行地址激活， 只更新列地址，减少了行地址设置时间，提高处理效率

 

**预充电与激活**

当我们在更新行地址信息是，需要停止已经锁定的行信息， 对新行进行预充电。这个过程会造成一定延时。这个延时记做tRP。

![](https://garlicspace.com/wp-content/uploads/2021/10/cpumemory.11.png)

- 预充电信号没有特殊的专线信号，一般实现如图，使用WE和RAS低电平来实现。
- 图中的预充电过程与数据传输重叠，并且比数据传输时间多了一个周期。

以上两个图中的涉及延时参数：

- CAS Latency （CL) ： 列地址生效延时
- RAS\-to-CAS delay (tRCD)；行地址生效到开始传输列地址
- RAS Precharge (tRP)： 行地址预充电
- Active to Precharge delay (tRAS)：行地址激活

**重充电**

由于DRAM要不断刷新，这个时间段如果进行读写将造成较大延时。

 

#### **内存类型**

- DDR1 比 SDRAM 增加了I/O buffer，与SDRAM只支持上升沿梳理数据，增加下降沿传输数据
- DDR2 比 DDR1总线频率提高
- DDR3 提高频率和总线宽度同时降低电压，减小功耗

DDR2， DDR3搭载模块数限制在4个模块，影响扩展，解决方式：

- NUMA ：内存控制器放入cpu
- FB-DRAM：采用串行总线替代并行总线，从而扩展可接入模块

 

#### **参考及引用：**

Photo by **from twitter** Ines B@moraimauy

