高性能存储的基础,了解一下内存的方方面面
百川归海-Edward  2024-08-05 16:58  发布于中国

文章转载自:数据存储张 公众号

 

在前面章节我们简要介绍过内存的相关内容,本节我们将详细的介绍一下内存的方方面面。本节所谓的内存聚焦在DRAM(Dynamic Random Access Memory)的范畴,DRAM在个人计算机、工作站和服务器等计算机系统中有着非常广泛的应用。内存实际上是一个比较简单的计算机设备,如图 1所示是常见内存条的实物图。不同类型计算机内存条的形态不太一样,这里是服务器上常用的内存条。可以看出在内存条上有很多集成电路,这些集成电路分为两类,一类是内存颗粒,内存颗粒是存储数据的实体,好比我们日常存储物品的仓库一样;另外一个是SPD(Serial Presence Detect),也就是串行存在检测芯片。

641.png

图1内存实物图

虽然一个计算机当中可能有多个内存条,每个内存条中有多个内存颗粒,但是控制器为我们做了很多抽象工作,在操作系统层面通常看到的是一个连续的线性空间。操作系统系统层面又会做很多工作,应用程序层面通常看到只是虚拟地址,而非真实的物理地址。

前面我们了解到对于硬盘的访问,是以扇区或者页为粒度。内存的访问粒度要小的多,我们可以以字节为粒度访问内存。前面我们介绍机械硬盘的时候了解到其随机访问性能要比顺序访问差很多,但内存的随机访问与顺序访问差异并不大。这些访问特性是内存与硬盘不同的地方。

我们先介绍一下SPD,这个集成电路其实就是一个存储芯片,里面存储着该内存条的一些特性参数。这些参数包括如类型、工作电压、工作频率和速度等信息。以内存类型为例,其中有一个名称为基本内存类型(Basic memory type )的字段用于描述内存的类型,比如对于DDR内存该字段的值是7,对于DDR2内存为8,对于DDR3内存该值为11。正是通过这些信息,CPU才能建立与内存之间的正常通信的。

另外需要注意的是,在内存条上并没有一个像SSD那样的控制器芯片,内存控制器通常集成在北桥芯片当中。早些时候北桥芯片是一颗独立的芯片,但大多已经集成在CPU当中了。

另外一个集成电路就是内存颗粒了,但我们暂时先不介绍这部分的内容,我们先从整体一下了解一下内存条。可以看出图 1‑35中上下两个内存条上内存颗粒的数量是不同的。上面那个内存条有8个内存颗粒,而下面那个内存条则9个内存颗粒。这是因为两个内存条是不同种类的内存条,上面那个是普通内存条,下面的内存条是具有ECC功能的内存条。

什么是ECC?ECC是纠错码(Error Correction Code)的简称,简而言之,具备纠错码功能的内存条可以实现纠错功能。其代价就是需要一个额外的内存颗粒。消费级的内存条通常不具备ECC,通常只有一些企业级的内存条才具备ECC的功能。原因很简单,具备ECC的内存条要贵不少。

内存条的ECC功能到底有没有必要?我们看一下金士顿公司关于ECC内存和非ECC内存故障率的统计,具体如图 2所示。从该图我们可以得到两个有用的信息,一个是非ECC内存的故障率大概在1%左右,对于企业级应用来说,这个故障率还是很高的。另外一个信息是ECC技术确实可以非常有效的改善内存的故障率。

641.png

图2内存故障率

那么ECC是如何降低内存故障率的呢?我们回过头来介绍一下ECC的原理。ECC是通过一个称为汉明码(Hamming Code)的方式实现纠错的。接下来我们介绍一下汉明码是如何实现纠错的。

在介绍汉明码之前,我们先介绍一下奇偶校验。奇偶校验是根据一个数据中二进制位中“1”的数量完成数据校验的方法。奇偶校验是两种不同的方法,分别是奇校验和偶校验。其中奇校验是通过校验位确保数据中有奇数个“1”;偶校验是通过校验位确保数据中有偶数个“1”。

以奇校验为例,我们简要介绍一下其实现的方法。其实方法是非常简单的,就是在原始数据的后面加一位数,这位数称为校验位,具体如图3所示。我们知道在一个二进制数中,“1”的个数要么是奇数个,要么是偶数个。通过新增的校验位,我们就可以保证数据中“1”的个数一定是奇数个。以数字17为例,其二进制数如图 3所示,其中“1”的个数为2。如果我们想实现奇校验,这时候将校验位设置为1即可。当然,如果原始数据中“1”的个数为奇数个,那么我们将校验位设置为0即可。偶校验与奇校验类似,只是偶校验要保证数据中“1”的个数为偶数个。依然以17为例,如果是偶校验,那么校验位应该设置为0。

641.png

图3奇偶校验示意图

通过奇偶校验的原理我们可以看出其缺陷,一个是奇偶校验只能完成校验,也就是验证数据中是否有出错的位,不能完成纠错。原因很简单,因为他是按照“1”的数量来检查的,并不知道具体是哪一个位发生了变化。第二个是对于两个位同时出错的情况,奇偶校验是检查不出来的。

有了奇偶校验的知识,我们接着看看汉明码的实现。汉明码不仅仅可以完成查错,还能够完成纠错。汉明码是通过多个校验位来完成纠错功能的,校验位数量k可以通过如下公式计算得到。在下面公式中,n是数据的位数,k是校验数据的位数。

641.png

为了更加清楚的了解校验数据位数k和数据位数n的关系,我们举几个例子。这里的校验数据位数是取的最小值,也就是纠错成本最低的值。校验数据越少,我们需要的额外的传输成本和存储成本就越低。如果我们从校验数据的位数可以完成纠错支持的最大数据位数的角度理解,可能会更加容易理解一些。

表1‑1汉明码数据位数与校验位数关系

截图20240805164704.png

以3位校验码为例,公式左侧的计算结果为7(23-1=7)。而此时校验数据位数k为3,因此可以支持的最大数据位数为4,也就是2位到4位的数据长度都可以用3位校验码完成纠错的功能。以此类推,如果校验数据为4位,那么最大可以支持11位数据。对于计算机的内存而言,目前主流为64位的内存,因此额外需要7位的空间用于存储校验数据,这也就是为什么ECC内存会多出来一个内存颗粒的原因。

前面我们从校验数据的数量上进行了介绍,那么这些校验数据与原始数据的关系是怎么样的呢?也是像奇偶校验那样放在原始数据末尾吗?这就涉及汉明码编码规则的问题。汉明码的具体规则包含两条:

1)数据位置的确定,包括校验数据的位置和原始数据的位置。其中校验码占位在2k-1,数据按照原始顺序填充

上述规则可能不太好理解,我们以4位数据(数字5)为例介绍一下。对于4位数的,根据公式我们知道校验位应该是3位,也就是总共7位。这条规则解决的是如何将4位原始数据和3位校验数据放在下面7位的空位当中。

641.png

图4汉明码数据位置

我们对空位进行了编号处理,从右往左依次为,1,2,3,…,7。在本规则中,校验码占位在2k-1,也就是分别是1,2,4三个位置。原始数据按照相对位置填充到其他空位当中,具体如图 5所示。

642.png

图5汉明码数据位置实例

2)校验数据值的确定。位置确定了,接下来就是要确定校验数据的值了。具体校验位值的计算也是通过奇偶校验类似的方法得到的,但核心问题是选择哪几位做运算。接下来我们看看具体的规则。

我们将位置编号转换为二进制的值,具体如图6所示。对于位置1的校验位的计算选择第1位(从右往左数)为1的位置编号作为一组。因此,对于校验位1,选择1、3、5和7进行校验,如果采用偶校验,那么此时值应该为1。

同理,对于位置2的校验位的计算选择第2位为1的位置编号作为一组。因此,对于校验位2,选择2、3、6和7进行校验,此时校验值为0。对于校验位3,其位于编号为4的位置(0100),因此选择第3位为1的位置编号作为一组,最终计算的结果为1。

641.png

图6汉明码校验位计算规则

经过上述实例分析,大家应该清楚汉明码的分组和计算规则了吧。经过上述计算,我们最终可以得到7位数据的值为0101101。

校验数据的值确定了。如果出现了数据错误,汉明码是怎么纠正错误的呢?我们依然一个具体的例子进行说明。假设上述数据第5位出现了问题,我们在分组进行偶校验的时候一定可以发现。如图 7所示,按照原来的分组方法,第5位的数据分别包含在两个不同的分组当中,可以看到两个分组中1的个数已经不是偶数个。所以可以断定一定有数据出现了错误。

641.png

图7汉明码纠错算法

但具体是哪一位的数据出现了错误呢?方法也非常简单,我们依然按照偶校验的方式补齐1的个数,此时可以分别计算出3组数的值如图 7中蓝色方块所示。然后将得到的值从下往上组成一个二进制的数就是出错数据的具体位置,本例为101(5)。

接下来我们继续内存条物理结构的介绍。前文我们知道内存条是由多个内存颗粒构成的,如图 8条是由8颗内存颗粒构成的。内存颗粒都是由多个BANK构成的,BANK可以独立寻址的存储单元。

641.png

图8内存颗粒内部结构

每个BANK包含一个内存矩阵,同时包含列解码和行解码单元,通过编码器实现阵列的定位和数据的读写。我们进一步深入到存储矩阵,如图 9所示,矩阵中包含海量的DRAM单元。每个DRAM单元可以存储一个比特(bit)的数据。

641.png

图 9RANK局部放大图

那么DRAM单元是如何存储数据的?原理非常简单,如图 9右侧是DRAM单元的放大图,每个单元由一个晶体管和一个电容组成。DRAM单元就是通过电容中是否有电荷来表示“0”和“1”的,如果电容中的电荷达到一定的阈值那么表示“1”,否则表示“0”。由于电容会漏电,因此DRAM需要定时刷新,避免漏电导致的数据错误。

至此,我们介绍了DRAM的最主要的内容。希望大家能够学到有用的内容。 后面本号会继续介绍更多关于内存的相关知识。

全部回复(
回复
回复