上一篇“流量统计”中,我介绍了MC中的计数器:UNC_M_RD_CAS_RANK0.ALLBANKS ,但最后perf的示例中,演示的是所有读流量统计。
所有读流量统计比较简单,RANK层流量统计,会复杂一些。但掌握了它,还可以在更细致的BG层、BANK层统计流量。
通过分析流量,你可以知道你要访问的内存到底走了那个通道、落在那个RANK、那个BG和BANK中。你将亲身经历一个内存的虚拟地址,是如何转变、映射,最终落到那个BANK的那一列中,内存是如何把数据传输给CPU,……等等。
Precharge、刷新、行选通、CAS……,等等干巴巴的枯燥概念,成为可以观察、可以研究的对象。你将彻底理解内存是如何被使用的。
只有了解了底层,才能清楚的明白,什么情况下算力只是纸面上的,什么情况下算力可以被真正的发挥。
在这个激动人心时刻到来之前,我们还需要学习一个概念:内存通道,Channel。
在图1的左右两边,有两个蓝色的块块,是MC,内存控制器,这个我们前面说到过了。Intel觉得MC名字不够响亮,又起了一个名字:IMC(Integrated Memory Controller)。后面会混用MC、IMC,都是指内存控制器。
图1有两个IMC:IMC0和IMC1。每个IMC中有三条内存通道,其中IMC0每条通道连接两个内存插槽,IMC0一共可连接6个内存插槽。
IMC1也一样啊,图中没有画全。两个IMC共可连接12个内存插槽,也就是共可连接12根内存条。
内存通道名字中既然有“通道”二字,它肯定像道路一样,连接着CPU和内存。也的确是这样,每个内存通道都有64位宽的总线(实际上比64位要宽,因为还要传输控制信号)。
CPU和内存间总吞吐量,是所有内存通道的总和。
除了“通道”的外,内存通道还有“控制”的作用。它要从物理地址中得到RANK号、BG号、BANK号、行号、列号,然后发出ACT命令(激活命令)、READ/WRITE命令,或Precharge、刷新等命令。
另有一个概念:内存时序。在开机内存上电时,CPU会从内存芯片中读取时序信息。时序是内存完成ACT命令(激活命令)、READ/WRITE命令等各种命令的时间,以内存Chip的频率为准,单位是周期。
因为内存通道和内存条的交互不是一次性的,并不是“我告诉你地址,你给我数据“,而是分阶段。在这个过程中,时序扮演着十分重要的角色。
经过前面8篇文章的讲述,我们已经知道内存包括RANK、BG、BANK、行、列等结构。内存通道要先依据规则,从物理地址中得到RANK号、BG号、BANK号、行号、列号。
这里我提一点,“内存通道要先依据规则",这个规则,被称为编址规则。记住,它非常的重要,但为了避免主题分散,本篇不展开讲它。它会是内存系列后面几篇的“灵魂”之一。
Page,这个概念本来准备留到“实测”阶段、结合实测结果细说的,这里先提一下吧。
图2是8位宽BANK,它里面有8组Memory Array。
每个Memory Array下面都有一个Row Buffer,8个Memory Array的Row Buffer合起来,就是Page。
根据 JEDEC 标准,Memory Array的宽度是固定的,1024个bit。
列宽度是1024bit,也就是Memory Array中一行的大小是1024bit,乘以8,Bank的页大小8192bit,即页的大小为1024B(大写B,字节)。
我们不会只读写一个BANK,是按RANK,一次读写8个BANK(8位宽情况下),那么,还要再乘以个8,1024B*8,8192字节,这个也是页大小,是RANK层的页大小。
我在阅读一些文档时,有些文章说页是1024B,有些说是8192B,其实就是有些是针对一个BANK、有些是针对RANK。这一点我们要注意。
软件层并不直接动手装内存颗粒,对有些名词的使用,没有那么精准。
了解了页的概念,页命中(page hit)就简单,内存通道收到一次读,通过编址规则计算,从物理地址中分解出RANK号、BG号、BANK号、行号、列号,发现这次要读的数据正好和前一次是相同的RANK、BG、BANK、行,不同的列(都到内存通道层了,L1~L3 Cache,显然没有命中),这就是页命中了。
页命中后又能怎样呢?内存通道接下来又会干什么呢?本篇讲不完了,下一篇,我们继续详细描述CPU内存操作的具体步骤。