1、内存的工作原理及时序介绍第一部分:工作原理DRAM 基本组成内存是由 DRAM(动态随机存储器)芯片组成的。 DRAM 的内部结构可以说是 PC 芯片中最简单的,是由许多重复的“单元”cell 组成,每一个 cell 由一个电容和一个晶体管(一般是 N 沟道 MOSFET)构成,电容可储存 1bit 数据量,充放电后电荷的多少(电势高低)分别对应二进制数据 0 和 1。由于电容会有漏电现象,因此过一段时间之后电荷会丢失,导致电势不足而丢失数据,因此必须经常进行充电保持电势,这个充电的动作叫做刷新,因此动态存储器具有刷新特性,这个刷新的操作一直要持续到数据改变或者断电。而MOSFET 则是控制电
2、容充放电的开关。 DRAM 由于结构简单,可以做到面积很小,存储容量很大。内存地址内存中的 cell 按矩阵形排列,每一行和每一列都会有一个对应的行地址线路(正规叫法叫做 word line)和列地址线路(正规叫法是 bit line) ,每个具体的 cell 就挂接在这样的行地址线路和列地址线路上,对应一个唯一的行号和列号,把行号和列号组合在一起,就是内存的地址。上图是 Thaiphoon Burner 的一个 SPD dump,每个地址是一个字节。不过我们可以把这些数据假设成只有一个 bit,当成是一个简单的内存地址表,左边竖着的是行地址,上方横着的是列地址。例如我们要找第七行、倒数第二列
3、(地址为 7E)的数据,它就只有一个对应的值:FD。当然了,在内存的 cell 中,它只能是 0 或者 1。寻址数据要写入内存的一个 cell,或者从内存中的一个 cell 读取数据,首先要完成对这个 cell 的寻址。寻址的过程,首先是将需要操作的 cell 的对应行地址信号和列地址信号输入行/列地址缓冲器,然后先通过行解码器(Row Decoder)选择特定的行地址线路,以激活特定的行地址。每一条行地址线路会与多条列地址线路和 cell 相连接,为了侦测列地址线路上微弱的激活信号,还需要一个额外的感应放大器(Sense Amplifier)放大这个信号。当行激活之后,列地址缓冲器中的列地址
4、信号通过列解码器(Column Decoder)确定列地址,并被对应的感应放大器通过连接 IO 线路,这样 cell 就被激活,并可供读写操作,寻址完成。从行地址激活,到找到列地址这段时间,就是 tRCD。内存 cell 的基本操作内存中的 cell 可以分为 3 个基本操作,数据的储存、写入与读取。为了便于理解,我不打算直接从电路控制上对 cell 操作进行说明,而是希望通过模型类比来达到说明问题的目的,如有不严谨之处,高手勿怪。要对内存 cell 进行读写操作,首先要完成上述寻址过程,并且电容的充电状态信号要被感应放大器感应到,并且放大,然后 MOSFET 打开,电容放电,产生电势变化,把
5、电荷输送到 IO 线路,导致线路的电势也变化。当然,这只是个简单的描述,以下我们先来了解硅晶体中“电容”的结构和 MOSFET 的控制原理。硅晶体中的“电容”这里之所以“电容”两个字被打上引号,是因为硅晶体中并没有真正意义上的电容。硅晶体中的电容是由两个对置的触发器组成的等效电容。例如两个非门(Nor Gate)用如下图的方式对接。它可以通过周期性施加特定的输入信号,以把电荷保留在电路中,充当电容的作用。如下图,两个非门的输入端 R 和 S 互相交替做 0 和 1 输入,就可以把电荷储存在电路中。整个动态过程就是这样:而 R 和 S 的波形就是如下图所示,刚好互为反相,差半个周期:要让电容放电
6、,我们只需要把 R 和 S 同时输入 1 或者 0 即可。因此这种电容的逻辑关系很简单:在同一时刻 R 和 S 输入状态不同(即存在电势差)时,电容为充电状态;在同一时刻 R 和 S 输入状态相同(即电势差为 0)时,电容为放电状态。MOSFET 的控制原理水库模型要说明这个 MOSFET 的控制原理,我们借助一个水库的模型来说明。MOSFET 有三个极,分别是源极(Source) 、漏极(Drain)和栅极(Gate ) 。下图左边就是一个 MOSFET 的电路图,右边是我们画出的一个水库模型。图中 S 为源极,D 为漏极,G 为栅极。S 极连接着电容,D 级连接列地址线路,并接到数据IO,
7、G 则是控制电荷流出的阀门,连接行地址线路。电容在充电后电势会改变,这样 S 极的电势就会跟着改变,与 D 极形成电势差,而 G 极的电势,就决定了 S 极有多少电荷可以流入 D 极。由于电子是带负电荷,因此电子越多电势就越低。为了不至于混淆概念,我们把水池顶部电势定为 0V,水池底部电势定为 5V(仅举例说明, DRAM 中的电容实际电压未必是 5V) 。当电子数量越多时,电势越低,接近 0V,电子数量越少时,电势越高,接近5V。用水库模型说明,就是左边的水池水量升高(电容充电后) ,当阀门关闭时,左边的水是不会往右边流的。然后阀门打开(降低,电势升高) ,左边的水就可以往右边流,阀门的高度
8、就决定了有多少水能流去右边的水道(但是在数字电路中,MOSFET 只有开和关两种状态,因此下文提到的打开 MOSFET 就是全开) ;同样道理如果右边水多,阀门打开之后也可以向左边流。因此在水库模型中,电容就充当了左边的水池,而 MOSFET 的栅极就充当了阀门,列地址线路和 IO 则充当了右边的水道。储存数据MOSFET 栅极电势为 0V 时,电容的电荷不会流出,因此数据就可以保存我们可以用 2.5V为参考分界线,电容电势低于 2.5V 时,表示数据 0,电势高于 2.5V 时,表示数据 1。例如上一楼水库模型的左图,电容中储存的电子数高于一半的高度,电势低于 2.5V,因此可以表示数据 0
9、。但以上只是理论情况,实际上电容会自然漏电,电子数量会逐渐减少,电势就会逐渐升高,当电势升高到 2.5V 以上时,数据就会出错,因此每隔一段时间必须打开MOSFET 往电容中充电,以保持电势,这就是刷新。因此,数据的储存主要就是对电容中电势的保持操作。写入数据数据写入的操作分为写入 0 和写入 1 两种情况。写入前,电容原有的情况可能是高电势与低电势的状态,我们不用管它。写入 0 和写入 1 对 cell 的操作不尽相同,我们分别来看。先来看写入 0 的操作。写入开始时, IO 线路上电势为 0(水道处于水位最高点) ,MOSFET栅极电势升高到 5V(水库阀门降到最低) ,阀门打开,电容中的
10、电势就跟着降低(水位升高) ,直到接近 0V(水池被灌满) ,写入 0 完成,栅极电势降回 0V,阀门关闭。再看写入 1 的操作。写入开始时, IO 线路上的电势为 5V(水道水位为最低点) ,MOSFET栅极电势升高到 5V(水库阀门降到最低) ,阀门打开,电容中的电势跟着升高(水流出并降低水位)到接近 5V,写入 1 完成,栅极电势回到 0V,阀门关闭。读取数据读取的时候,对漏极的电压操作跟写入有些不同。因为水道中的水比水池中的多,或者说水道的容量比水池要大得多。如果水道(漏极)的水为满或者空,在阀门打开的时候很容易出现水道的水倒灌进水池的现象,或是水池的水全部流去水道,这样就有可能导致电
11、容中的电势状态改变,电容对应储存的 0 或者 1 也会改变。所以读取数据的时候, IO 线路的电压应为 1/2 的满电势,即 2.5V。读取也同样分读取 0 和 1 两种情况。在读取之前,电容中的电势应该是大于或者小于 2.5V的,分别代表存储了 1 和 0。由于刷新机制的存在,应该不会允许出现等于 2.5V 的情况。首先看读取 0 操作。电容中为低电势(假设为 0V,水池为高水位) ,IO 线路上电势升高至2.5V(这时水道水位比水池低) ,MOSFET 栅极电势升高到 5V(水库阀门降到最低) ,阀门打开,电容中电势升高(水位降低) ,但由于水道容量较大,因此水位不会升高太多,但是总归也会
12、有个电势的变低,最终电容与 IO 线路上的电势都变成 0-2.5V 的一个中间值,并且接近 2.5V(假设为 2.3V) 。这时候感应放大器检测到 IO 线路上电势低于 2.5V,因此识别出 0 读出。再看读取 1 操作。电容中为高电势(假设为 5V,水池空) ,IO 线路上电势升高至 2.5V(这时候水道水位比水池高) ,MOSFET 栅极电势升高到 5V(水库阀门降到最低) ,阀门打开,电容中电势降低(水位升高) ,但由于水道容量较大,水位不会降低太多,不过多少也会降低一点(电势会升高) ,假设升高到 2.7V。这时候感应放大器检测到 IO 线路的电势高于2.5V,识别出 1 读出。以上讲
13、述的只是从 cell 到内存 IO 线路的读写操作,至于 CPU-IMC-内存的读写操作,不在本文讨论范围。第二部分:时序介绍时序及相关概念以下我把时序分为两部分,只是为了下文介绍起来作为归类,非官方分类方法。第一时序:CL-tRCD-tRP-tRAS-CR,就是我们常说的 5 个主要时序。第二时序:(包含所有 XMP 时序)在讲时序之前,我想先让大家明白一些概念。内存时钟信号是方波,DDR 内存在时钟信号上升和下降时各进行一次数据传输,所以会有等效两倍传输率的关系。例如 DDR3-1333 的实际工作频率是 666.7MHz,每秒传输数据 666.7*2=1333 百万次,即 1333MT/
14、s,也就是我们说的等效频率 1333MHz,再由每条内存位宽是 64bit,那么它的带宽就是:1333MT/s*64bit/8(8bit 是一字节)=10667MB/s。所谓时序,就是内存的时钟周期数值,脉冲信号经过上升再下降,到下一次上升之前叫做一个时钟周期,随着内存频率提升,这个周期会变短。例如 CL9 的意思就是 CL 这个操作的时间是 9 个时钟周期。另外还要搞清楚一些基本术语:Cell:颗粒中的一个数据存储单元叫做一个 Cell,由一个电容和一个 N 沟道 MOSFET 组成。Bank:8bit 的内存颗粒,一个颗粒叫做一个 bank,4bit 的颗粒,正反两个颗粒合起来叫做一个 b
15、ank。一根内存是 64bit,如果是单面就是 8 个 8bit 颗粒,如果是双面,那就是 16 个4bit 的颗粒分别在两面,不算 ECC 颗粒。Rank:内存 PCB 的一面所有颗粒叫做一个 rank,目前在 Unbuffered 台式机内存上,通常一面是 8 个颗粒,所以单面内存就是 1 个 rank,8 个 bank,双面内存就是 2 个 rank,8 个bank。Bank 与 rank 的定义是 SPD 信息的一部分,在 AIDA64 中 SPD 一栏可以看到。DIMM:指一条可传输 64bit 数据的内存 PCB,也就是内存颗粒的载体,算上 ECC 芯片,一条 DIMM PCB 最
16、多可以容纳 18 个芯片第一时序CAS Latency(CL):CAS 即 Column Address Strobe,列地址信号,它定义了在读取命令发出后到数据读出到 IO 接口的间隔时间。由于 CAS 在几乎所有的内存读取操作中都会生效(除非是读取到同一行地址中连续的数据,4bit 颗粒直接读取间隔 3 个地址,8bit 颗粒直接读取间隔 7 个地址,这时候 CAS 不生效) ,因此它是对内存读取性能影响最强的。如下图,蓝色的 Read 表示读取命令,绿色的方块表示数据读出 IO,中间间隔的时间就是 CL。已知 CL 时钟周期值 CAS,我们可以使用以下公式来计算实际延迟时间 tCAS:t
17、CAS(ns)=(CAS*2000 )/内存等效频率例如,DDR3-1333 CL9 内存实际 CAS 延迟时间=(9*2000)/1333=13.50 ns或者反过来算,假如已知你的内存可以在 7.5ns 延迟下稳定工作,并且你想要 DDR3-2000的频率,那么你可以把 CL 值设为 8T(实际上 8ns,大于 7.5ns 即可) ,如果你想要 DDR3-1600 的频率,那么你的 CL 值可以设到 6T(实际 7.5ns) 。这个公式对于所有用时钟周期表示延迟的内存时序都可以用。说到这个公式,我想顺便说说大家对频率和时序的纠结问题。首先来回顾一下 DDR 一代到三代的一些典型的 JEDE
18、C 规范,并按照上边那个公式算一下它的 CL 延迟时间:DDR-400 3-3-3-8:(3*2000)/400=15 nsDDR2-800 6-6-6-18:(6*2000)/800=15 nsDDR3-1333 9-9-9-24:刚才算了是 13.5 ns再来看看每一代的超频内存的最佳表现(平民级,非世界纪录):DDR1 Winbond BH-5 DDR-500 CL1.5:(1.5*2000)/500=6 nsDDR2 Micron D9GMH DDR2-1400 CL4:(4*2000)/1400=5.71 nsDDR3 PSC A3G-A DDR3-2133 CL6:(6*2000)
19、/2133=5.63 ns发现什么?不管是哪一代内存,随着频率提升,CL 周期也同步提升,但是最后算出来的 CL延迟时间却差不多。那么到了 DDR4,JEDEC 规范频率去到 DDR4-4266,如果按照差不多的延迟,那么按照 13ns 多一些来算,那么 CL 值将达到 28T!如果按照我们的极限超频延迟来算,DDR4-4266 下的延迟也将达到 12T。所以到了下一代 DDR4,两位数的时钟周期将不可避免。所以,我想说的是,不要再去想什么 DDR3 的频率,DDR2 的时序,在频宽严重过剩,IMC成为瓶颈的今天,它对性能没太多的提升。DRAM RAS to CAS Delay(tRCD):R
20、AS 的含义与 CAS 类似,就是行(Row)地址信号。它定义的是在内存的一个 rank(内存的一面)之中,行地址激活(Active)命令发出之后,内存对行地址的操作所需要的时间。每一个内存 cell 就是一个可存储数据的地址,每个地址都有对应的行号和列号,每一行包含 1024 个列地址,当某一行地址被激活后,多个 CAS请求会被发送以进行读写操作。简单的说,已知行地址位置,在这一行中找到相应的列地址,就可以完成寻址,进行读写操作,从已知行地址到找到列地址过去的时间就是 tRCD。当内存中某一行地址被激活时,我们称它为“open page”。在同一时刻,同一个 rank 可以打开 8 个行地址
21、(8 个 bank,也就是 8 个颗粒各一个) 。下图显示一个行地址激活命令发出,到寻找列地址并发出读取指令,中间间隔的时间就是 tRCD。tRCD 值由于是最关键的寻址时间,它对内存最大频率影响最大,一般想要上高频,在加电压和放宽 CL 值不奏效的时候,我们都要放宽这个延迟。DRAM RAS Precharge Time(tRP):RAS 预充电时间。它定义的是前一个行地址操作完成并在行地址关闭(page close)命令发出之后,准备对同一个 bank 中下一个行地址进行操作,tRP 就是下一个行地址激活信号发出前对其进行的预充电时间。由于在行地址关闭命令发出之前,一个 rank 中的多个
22、行地址可能正在被读写, tRP 对内存性能影响不如 CL 和tRCD。虽然 tRP 的影响会随着多个行地址激活与关闭信号频繁操作一个 bank 而加大,但是它的影响会被 bank interleaving(bank 交叉操作)和 command scheduling(命令调配)所削弱。交叉读写会交替使用不同的 bank 进行读写,减少对一个 bank 的操作频率;命令调配则是由 CPU 多线程访问不同的内存地址,同样是减少对一个 bank 的频繁操作次数。例如SNB CPU 的内存控制器可以对读写操作命令进行有效地重新分配,以使得行地址激活命中率最大化(如果重复激活一个已经处于激活状态的行地址
23、,那就是 RAS 激活命令未命中) ,所以 tRP 在 SNB 平台对性能的影响不大,并且放宽它有可能可以帮助提升稳定性。下图显示的是一个即将被激活的行地址开始预充电,到它被激活间隔的时间,就是 tRP。DRAM RAS Active Time(tRAS):行地址激活的时间。它其实就是从一个行地址预充电之后,从激活到寻址再到读取完成所经过的整个时间,也就是 tRCD+tCL 的意思。这个操作并不会频繁发生,只有在空闲的内存新建数据的时候才会使用它。太紧的 tRAS 值,有可能会导致数据丢失或不完整,太宽的值则会影响内存性能,尤其是在内存使用量增加的时候。所以一般为了稳定性,我们设置 tRASt
24、RTP+tRCD+CL 即可(tRTP 不是 tRP,将在第二时序中介绍) ,尤其是 PCB 不好或者跑高频的时候,多几个周期比较稳妥。DRAM Command Mode(Command Rate,CR):首命令延迟,也就是我们平时说的 1T/2T模式。是指从选定 bank 之后到可以发出行地址激活命令所经过的时间。CR 可能对性能的影响有比较大的变数:如果 CPU 所需要的数据都在内存的一个行地址上,就不需要进行重复多次的 bank 选择,CR 的影响就很小;但是如果一个 rank 中同时多个 bank 要激活行地址,或者不同的 rank 中不同 bank 需要同时激活的时候, CR 对性能
25、的影响就会提升。但是随着内存频率的提升,CR=1T/2T 的时间差越短,它的影响就会越来越小,这就是我们看到DDR1 的时候 1T/2T 对性能影响挺大,但是到了 DDR3 影响就很小的其中一个原因。但是为了性能最大化,我们尽量把 CR 设为 1T,但是如果 bank 数很多的时候,例如插满四条内存,就有 32 个 bank,bank 选择随机性增大, 1T 的首命令时间可能会不稳定。所以,内存的基本读取操作的时序角度流程就是把上面那三张图合起来:预充电-激活行地址并寻找列地址-发送读取命令-读出数据,这四步操作中间的三个延迟就分别是 tRP、tRCD和 CL。和我们常说的时序顺序刚好是反过来
26、的。第二时序XMPDRAM CAS Write Latency(tWCL ):列地址写入延迟,也就是 DRAM 的最小写入操作时间,与 CL 刚好是读写对应关系,一般跟 CL 值设为同一个值就是可以稳定的。由于内存读取之前必须先写入,所以这个值可以说与 CL 一样重要。但是在 BIOS 里一般没得设置,可能是与 CL 绑定了。DRAM Row Cycle Time(tRC):行周期时间。定义了同一 bank 两次行激活命令所间隔的最小时间,或者说是一个 bank 中完成一次行操作周期(Row Cycle)的时间,即tRP+tRAS(预充电加上激活的整个过程) ,tRC 设得太紧可能会直接点开不
27、了机,一般只要能进系统再多加一两个周期都是可以稳定的。下图显示的就是 tRC 的时间。DRAM Row Refresh Cycle Time(tRFC):行地址刷新周期,定义了一个 bank 中行地址刷新所需要的时间。重提一下刷新的含义,由于 cell 中电容的电荷在 MOSFET 关闭之后一段时间就会失去,为了维持数据,每隔很短一段时间就需要重新充电。这里多提一句,Intel 平台和 AMD 平台对 tRFC 的含义不一样, AMD 平台的 tRFC 是 DRAM 刷新延迟时间,单位是ns,通常有 90/110/160/300 几个值可以调整,也就是说它的 tRFC 时钟周期会随着频率的提升
28、而提升;而 Intel 平台的单位则直接是时钟周期,相反地延迟时间会随着频率的提升而降低。容量大的 bank 行地址和 cell 会更多,刷新时间也更长,因此 tRFC 也要更高。另外,tRFC 如果太快会导致数据出错,太慢则影响性能,但可以增加稳定性。DRAM Refresh Interval(tREFI):内存刷新时间间隔,也就是内存的刷新命令生效前要经过的时间。刷新的时间间隔一般取决于内存颗粒的容量(density) ,容量越大,就越需要频繁刷新,tREFI 值就要越低。另外 tREFI 的时间也会受到内存工作温度与内存电压(Vdimm)影响,因为温度越高电容漏电越快。一般在 AMD 主
29、板的 BIOS 里,这个值只有 3.9us 和7.8us 可选,而在 SNB 平台,则是按时钟周期算,例如 DDR3-1333 下默认值为 5199T,换算过来就是 2000/1333x5199=7800ns,也就是 7.8us。一般 DRAM 颗粒的 spec 中都是规定工作温度大于 85 度时采用 3.9us。DRAM RAS to RAS Delay(tRRD):行地址间延迟,定义的是同一 rank 不同 bank 间两个连续激活命令的最短延迟,在 DDR3 时代一般最小是 4T。它的作用和 CR 有点像,不过比 CR更多的时候对性能有较大的影响,所以这个时序可尽量缩小。DRAM Wri
30、te Recovery Time(tWR):内存写入恢复时间,它定义了内存从写入命令发出(从开始写入算起)到下一次预充电间隔的时间,也就是 tRP 的前一个操作。如果这个时间设得太短,可能会导致前一次写入未完成就开始下一次预充电,进行寻址,那么前一次写入的数据就会不完整,造成丢数据的情况。这个周期也是第二时序中比较长的,DDR3-2000 一般需要 10-14 个周期,甚至更高。DRAM Read to Precharge Time(tRTP ):与 tWR 类似,定义了同一 rank 上内存从读取命令发出到 tRP 之前的间隔时间,但是它在读取完成并且行地址关闭之后才会生效。单颗128MB
31、的内存颗粒可以在 DDR3-2000 下运行在 4 到 6 个时钟周期,如果 bank 容量增大时,这个时序有可能要放宽。DRAM Four Active Window(tFAW):它定义了同一 rank 中允许同时发送大于四个行激活命令的间隔时间,因此最小值应该不小于 tRRD 的四倍。在 DDR3 上,tRRD 的最小值是4T,因此 tFAW 的最小值就是 16T。这个 tFAW 由于是在一个 rank 中大于四个 bank 同时激活之后才生效,因此在内存不是很繁忙的时候,它对性能的影响并不是很大。但是对一些频繁读写内存的操作(例如 SuperPI 32M) ,tFAW 对性能的影响可能会
32、加大。由于现在内存用满的几率非常非常小,两根双面的内存更是有 4 个 rank,配合上 interleaving,一个 rank中同时激活大于四个 bank 的几率应该不大,所以通常我们把它设为 tRRD 的四倍应该就不会出问题。DRAM Write to Read Delay(tWTR ):内存写-读延迟,它定义的是内存写入命令发出后到下一个读取命令之间的时间间隔,最小为 4T,与 tRTP 类似,提升内存的频率或者容量提升时,这个值需要提高。结语看完以上内容,我们已经对时序有了个大致的了解,现在应该可以知道一些时序设置时要注意什么了。比如 tFAW 要设为 tRRD 的四倍,tRAS 不能设太低等等。还是那句话,内存是辅助 CPU 超频的,时序设置只是为了放开内存更多的超频空间,时序本身对性能的影响很小,并且随着频率的提升,或者 bank 数的增加,这种影响可能会进一步减小。具体不同的内存颗粒也会有不同的设置情况,还请大家多关注本站的颗粒汇总以及最新内存颗粒测试报告!