703-主存的工作原理
# 703-主存的工作原理
主存,我们通常也叫做内存,这是计算机当中非常重要的一个部件。冯诺依曼把计算机分成了五大组成部分,其中存储器实际指的就是这个部件。那今天,我们就以 PC 机当中常用的组成为例,来看一看这个部件的工作原理。
# DRAM 芯片的内部结构
我们还是从 DRAM 芯片的内部结构开始说起。 DRAM 芯片以一个存储阵列为核心, 这个存储阵列以行列的形式组织, 那么行列的交点就是一个存储单元。 每个存储单元都有唯一的一组行列地址指定。 那么这样一个存储单元一般由若干个比特构成,常见的有 4 比特或者 8 比特, 而每一个比特都是由这样的一个基本电路构成。 通常情况下,DRAM 芯片的外观是这样的。 而在这里,有 8 个 DRAM 芯片焊接在这样一块绿色的小电路板上, 构成了一个内存模组,这也就是我们通常所说的内存条。
因此,从外部给入了行地址和列地址之后,这些地址会同时送到每一个 DRAM 芯片, 从而在每个 DRAM 芯片当中选中对应的一个存储单元。 如果每个 DRAM 芯片送出 8 个比特,那它就可以向外同时送出 64 个比特。
因此,如果从 CPU 送到内存条一组行列地址, 那内存条就可以返回这组地址所对应的, 一个 64 位的数。这就是一个数据在内存当中大致的存放方式。
当然我们也可以不用内存条的形式, 尤其是对于平板电脑和智能手机,它们本来体积就很小, 很难容纳内存插条这样大个的组件,而且它们也不一定需要这么多的 DRAM 芯片,所以往往是在它们的主板上直接焊接 DRAM 芯片。 但不管是哪种情况,一般都是由若干个 DRAM 芯片构成了计算机的主存储器, 也被称为内存。
那么就来看一看 CPU 是怎么访问内存的。 我们以 SDRAM 作为例子来说明这个访问的过程。 SDRAM 就是同步的 DRAM。 那在计算机内部,CPU 通过系统总线连接到了内存控制器, 而内存控制器再通过系统总线连接到了内存条,我们在这里着重画出了其中一个 DRAM 芯片, 那实际上内存控制器会把相关的地址线、数据线连接到内存条上的各个 DRAM 芯片, 那当 CPU 需要访问存储器时,
那首先要申请系统总线,在获得总线控制权后会将地址发到内存控制器中, 对于一个 32 位 CPU,那这个地址一般就是 32 位的。注意在这个时候, 地址并不会分成行地址和列地址,而是只有一个地址。
然后内存控制器会将这个地址进行分解,形成行地址和列地址等多个部分。然后内存控制器就会向 DRAM 芯片发起访存操作。
在这一步,可能会包括两个部分,一是称为预充电的这个操作, 这里打了中括号,代表了这是一个可能有也可能没有的操作, 那么就放在后面再说。然后进行行访问,也就是发出行地址。 通过存储总线发出的行地址会被 DRAM 芯片当中的行译码器接收到,就会在存储阵列中选中对应的那一行, 然后这一行当中的所有的存储单元的信号都会被经过放大之后放入到一个缓冲区当中,那这个过程就会被称为激活,或者是行访问的过程。那么只有等这个行缓冲区的信号都稳定了,我们才可以进行下一步的操作。
因此,我们需要关注的一个时间,就叫做 tRCD,这是从行选到列选的延迟。我们简单地来看一下这个时序图。假设在这个时钟上升沿,我们发出了行地址, 那么我们必须等待 tRCD 这么长的时间,才可以去进行下一步的操作,也就是发出列地址。那这个时间的长短是由这个 DRAM 芯片本身的特性决定的。一般来说,它的质量越好,这个时间就越短。 而对同样一个 DRAM 芯片,它的工作环境越好,这个时间也会越短。
那么等 tRCD 这段时间过去之后,我们就可以发出列地址了。 这时内存控制器就会把事先准备好的列地址发到 DRAM 芯片,由列译码器接收,虽然我们现在是把这个箭头画在这里,实际上内存控制器还是通过存储总线把这个列地址发过去的。我们另外画这条箭头只是为了看起来比较清晰。那么列译码器收到列地址之后,就会从缓冲区中选出对应的那一列, 如果现在要进行读操作,那被选中的这个存储单元的数,就会送到数据输出接口上去。而从发出列地址,到选出对应的存储单元的数这个过程, 就被称为列访问的过程。
那么列访问也是需要时间的。 这还是刚才那个时序图。从发出行地址到可以发列地址,中间要等待 tRCD 这么长的时间, 然后从发出列地址到选中的存储单元的数可以输出,也需要等待一段时间, 这段时间以 CL 标记,也就是从列选到数据输出的延迟。 而且通常情况下,访问内存都不会只读一个数,而是会连续读出多个数, 那么这些数会每一个时钟周期输出一个,依次地送到数据线上。
也正是因为如此,我们要事先把一整行的数, 都读到缓冲区里,因为它可以把每一个存储单元同时都连到了缓冲区中, 读出一个存储单元也是读,读出一整行来也是读,所花的时间并没有明显的差别。 所以不如一次把一整行都读出来,然后从中选择需要的连续的若干数据送出去, 而且这样还有另外一个好处,如果下一次访存还是在这同一行,那就不需要重复发这个行地址了。因为对应的行已经在缓冲区当中,只要直接发列地址就可以,这样就可以大大地缩短访存的时间。
那好,现在我们先回到这一次访问。 当 DRAM 芯片送出数据之后, 内存控制器就会采样对应的数据,然后将采样到的数据再送回到 CPU 当中去, 那过一段时间 CPU 又会发出访存的地址,那如果这次要访问的数据 和刚才要访问的数恰好在同一行,那就不需要再重新发行地址,只需要直接发列地址, 从缓冲区中选出对应的单元就可以了。
当然,如果下一次访问所要的数据不是这一行, 那么就需要把激活的这一行关闭, 这个过程我们称为预充电,实际上预充电最早可以在前一次传输,最后一个数据即将送出的时候开始, 因为我们不确定下一次传输到底会不会在同一行。
所以我们有两种可以选择的策略, 一种方式是等到新的传输开始,如果发现要访问的数据 不在已经被激活的这一行,那时再进行预充电, 这也就是刚才在步骤二中,我们提到的那个可能没有的预充电操作。 而另一种方式,则是在一次传输结束后就进行预充电。 这样在下一次的传输是同一行的概率不高的情况下,反而会获得更好的性能。
那么预充电也是需要花一定时间的,这个时间我们记为 tRP, 从内存控制器发出预充电的命令到 DRAM 芯片可以接收下一次行地址, 这段时间就被称为 tRP。
所以,虽然一个 SDRAM 有很多的性能参数,但是其中最关键的有这么几个,一是 tRCD,也就是从行选到列选的延迟时间, 在 PC133 这个标准当中,这个时间大约是 15 到 23 个纳秒, 因为 PC133 标准的时钟频率是 133 兆赫兹, 所以相当于 2 到 3 个时钟周期。 而 CL 这个参数,则指明了从列选到数据输出的延迟周期数, 注意它跟 tRCD 不同,tRCD 规定的是一个时间, 单位是纳秒,而 CL 规定的是一个时钟周期数的延迟, 在 PC133 标准中,这个参数是 2 到 3 个时钟周期,大约相当于 15 到 23 纳秒。
第三个重要的性能参数是 tRP,也就是行预充电的延迟时间。 同样在 PC133 标准当中,大约是 15 到 23 个纳秒,也相当于 2 到 3 个时钟周期。
我们以 PC133 标准的 SDRAM 为例,来看一个读操作的典型访问过程。 那么因为时钟频率是 133 兆赫兹,所以一个时钟周期 是 7.5 纳秒。那当内存控制器发出行地址之后, 需要等待 tRCD 时间,才能发出列地址, 然后等待 CL 个时钟周期,DRAM 芯片才会送出第一个数据, 这时内存控制器才可以采样,那么这个时间大约是 6 个周期,45 个纳秒。 随后每个周期 DRAM 芯片都会送出一个数据, 而每个数据的宽度,则取决于内存条上有几个 DRAM 芯片, 然后在最后一个数据送出之前,内存控制器可以发出预充电的命令, 再经过 tRP 的时间,就可以发出下一个访存操作的行地址了。然后后面, 再经过 tRCD 以及 CL 的时间,才会得到下一次访存的数据。 因为两次内存访问之间的时间间隔大约是 12 个周期,90 纳秒。 从这里我们也可以看出,虽然内存的时钟频率是 7.5 纳秒, 但并不意味着只需要 7.5 纳秒就可以得到想要的数据。
现在我们已经了解了 SDRAM 内存的基本结构和工作原理。 那近些年来,SDRAM 内存又有了长足的进步, 在下一节,我们就来看一看,这些 是如何发展的。