这是内存基础知识系列的第16篇,你可以到 基础软件开发 这里,找到前15篇。
测试程序非常简单,以64字节为步幅,重复的访问一段内存,然后使用PMC计数器,观察流量在那些RANK。当然,为了避免cache的影响,还需要使用clflush指令,将L1~L3中缓存的数据清理掉。
经过测试,内存流量以8KB为单位,在多个RANK间轮流切换。我因此得出这张内存流量分布图:
如图1所示,程序申请了一块内存,这块内存以8KB为单位,分布在内存条的4个RANK中。
那么,你有没有想过,这个神秘的页,在哪儿。我的意思是,由什么决定“页”的大小是8192B(字节)?
MC根据整根内存条和Chip的特性,决定以8192字节为单位分散存储数据、并访问内存。
而且8192B并不是固定的,要结合通道数量等基本概念。下面,我们就软、硬结合的,细细的扒一下“页”的定义到底来自哪里。
在内存基础知识(二)中,我着重介绍了Memory Array(也叫Sub Array)与Cell的概念。
一个Cell一个bit,比特。多个Cell合起来,构成二维的阵列,就是Memory Array:
在不能说的秘密--内存竟然有隐藏带宽中,我用dmidecode(或lshw -class memory)先查到内存颗粒(Chip)的型号,再到网上搜内存Chip的说明书。
[root@rdma101 ff]Getting SMBIOS data from sysfs.。。。。。。 Type: DDR4 Type Detail: Synchronous Registered (Buffered) LRDIMM Speed: 2133 MT/s ...... Part Number: M386A4G40DM0-CPB 。。。。。。
这是三星的DDR4内存,M386A4G40DM0-CPB,就是内存颗粒的型号。这是它的说明书:

就这一行:Row bits: 16,Column bits 10。行地址16位,列地址10位。
这就是Memory Array的大小。它的行用16个bit定位。16个bit,最大的地址是:1111,1111,1111,1111(二进制),十六进制为0xffff,十进制:65535。
列地址用10个bit寻址(定位),最大地址0x3ff,1023。0到1023,它共有1024个列。
知道了行、列数量,一个Memory Array的大小很容易计算出来,65536*1024,64Mb(小b),64M个比特。
上图的BANK由8个Memory Array组成。8个Memory Array共用相同的地址线,“它们是一致行动人,说访问第几行、第几列的bit,大家就都访问第几行、第几列的bit。”(来自内存基础知识(三)-- BANK的描述)。
Bank中Memory Array的数量,被称为内存Chip的位宽。上图就是8位宽的Chip。Memory Array大小再乘以8,就是Bank容量。
64Mb * 8,512Mb,64MB(大B)。也就是64M字节。
不过,示例中我的内存位宽不是8,是4。内存Chip的说明书有这项信息:
位宽为4,也就是Bank中有4个Memory Array。Bank大小为256Mb,32M字节。
只有4个Memory Array,连接Bank的数据线宽度也是4位,一次向外传输4个bit,还不够一个字节。所以,说到Bank大小,说字节没啥意义。Bank是按bit、不是按字节读写的。我换算为字节,只是为了让大伙更直观的感受到Bank的大小。
图6中上面红框中的信息,“SDRAM Density and Banks”,4Gb,就是一个Chip(内存颗粒)的总大小。
这个值是怎么算出来的呢,这就不得不再说下BG了,Bank Group。我在以下3篇介绍了BankGroup的概念:
BG(BankGroup简称)、Bank和Chip关系如下图:
这张图前面那些篇没有,是我这几年在为北京大学硕士阶段研究生讲授数据库时做的,这里拿出来给大家说明一下Chip、BG、Bank的关系。
内存条上的黑块块,就是Chip,也叫颗粒。一个Chip中包含多个BG,一个BG包含多个Bank。就这么简单,内存系列5、6、7说明了为什么要引入BG这层物理结构,这里不再复述。
图6 “SDRAM Density and Banks”中有写,“4BG&4Banks”。即,Chip中包含4个BG,每个BG有4个Bank。也就是,Bank大小“乘4再乘4”,就是一颗Chip的总大小了,即:
Chip总大小: 65536(行数量) * 1024(列数量) * 4(位宽) * 4(BG数量) * 4(Bank数量)
也就是图6 “SDRAM Density and Banks”中的 4Gb(小b),合计 512 MB字节。
内存系列第一篇不能说的秘密--内存竟然有隐藏带宽中,我们就讲到了RANK的概念。忘了可以再去复习下。
简而言之,以64位CPU、4位宽BANK为例,要16个Chip中的BANK合起来,才能组合成64位。
因为一个Bank的数据线是4位宽吗(对应的Chip数据线也是4位宽),16个BANK合起来(分布在16个Chip中),才能组成64位的数据线,也才能向CPU提供一个字、8个字节、64位数据。
16个Chip合起来,称为一个RANK。一个RANK可以为CPU完成读写请求。RANK之下的BG、Bank不行。
一个RANK多大呢?以4位宽为例,Rank中有16个Chip,再乘以16,得64Mb,8GB字节。
到这里,只差一步就能计算出整根内存条的大小了。
图6下面的红框,“Module Organization”中有写,4R*4,*4是位宽。4R,是4个RANK。
它有4个RANK,再乘以 4,就是整根内存条的大小,32GB字节。
计算这玩意,有啥用呢?
能算的出内存条大小,说明你大概了解了内存的内部结构,那么,“页”的概念,就容易理解了。
Memory Array一行1024b,4个Memory Array组合成一个Bank。CPU访问内存时,要16个Bank合力为CPU完成一次读写(这16个Bank分布在16个Chip中)。
我专门把这几个数字标红、加粗了,1024 * 4 * 16,就是 8KB。也就是在 内存基础知识(十四)-- 让内存条中的“页”现出原形 中观察到的页大小。
内存系列写到这儿,已经快要接近尾声了。我也不是搞FPGA、硬件的,我是搞数据库、基础软件和HPC的,我研究内存的目的何在?只为了满足好奇心吗?
当然不是了,下图进行类似矩阵乘法的操作,通过根据内存条特性安排数据分布,延迟降低了12%:
图8
图8的例子后几篇再说。页的概念还没有完,我们只是接近了真相。后面的系列,我们将彻底搞清楚“页”,本篇就到这里。