What Every Programmer Should Know About Memory Notes 0

28 Mar 2013

1 说明

原本想翻译,结果一看100+页,译了下第一页,然后就放弃了,改笔记。

2 Abstract

作者自然是看程序员都不懂硬件,代码写的太糟糕,内存、缓存统统都没用好,忍不住就给程序员定制一份硬件科普读物。

3 Introduction

说了下历史,之前是硬件简单,各部分性能都八九不离十,譬如改革前的天朝,大家穷才是真的穷,硬件么,就是大家慢才是真的慢。 好了,等基本结构稳定了,就开始贫富差距拉大了,拖祖国后腿的主要是两个玩意,存储系统、内存系统,一个2B,一个文艺。 2B的容易处理,操作系统还可以用内存当缓存,这个shell里面来个free -m就可以看到,但是内存没辙,太文艺,提高性能怎么都要涉及硬件,改造集中于以下:

  • RAM的硬件设计(速度与并发度)
  • 内存控制器的设计
  • CPU缓存
  • 设备的直接内存访问(DMA)

    下面就是文章结构等,等等等等。记住,针对的都是linux,别的么,认真你就输了。作者redhat的,当然不客气了。还有,讨论的问题有些在现实中不同实现差异比较大,所以别认真。

3.1 文章结构

  • 第二章,RAM的技术细节。
  • 第三章,CPU缓存细节。
  • 第四章,虚拟内存的实现。
  • 第五章,NUMA系统的细节1
  • 第六章,本文主要内容,集合前几章的内容,没耐心的可以从这里开始。
  • 第七章,工具。
  • 第八章,江湖规矩,展望。

4 Commodity Hardware Today

专业硬件正在滚蛋,商用硬件正在一统江湖。都是被一群互联网企业闹的,PC服务器群,便宜而且,便宜。Redhat,2007年的展望,未来数据中心都要用这样的:都是4插槽,每槽4核CPU,每CPU都超线程,但是没有英国管家。这个刚好够用,所以优化也集中于这点上。 不同机器结构不同,不过90%以上都在本文范围内,不过随时间变化也很大。

4.1 南北桥

貌似现在已经少了一个了?有些要合并和消失的趋势了?不过功能划分应该还是会有遗留的。 北桥速度要够快,南桥又叫I/O桥,看见IO就知道没救了。北桥主要是CPU与内存,南桥很多口的,还是北桥专一。 下面开始这一结构大批判:

  1. CPU与CPU之前通讯要走和北桥通讯一样的总线。
  2. 所有内存数据都要通过北桥
  3. RAM只有一个端口
  4. 南桥设备与CPU通讯要经过北桥,因为CPU在西北偏北么……

因为A.DMA占用北桥总线带宽而现在DMA的设备又爆多,总线么,是吧。B.北桥与RAM的总线,用的DDR2,双通道,貌似现在i7都有三通道了……爆兵堆数据果然在哪都是王道。然后CPU比内存快,这个大家都知道,所以最后的目的都是为了解决这个问题。下面的图就更加夸张了,每个内存都单独连内存控制器,再连北桥,缺点也有:北桥里面要撑爆了,外面往里狂灌数据。然后作者又提了下这么弄也可以弄成内存RAID,也是哦,这玩意和硬盘RAID也没什么差别了。然后,然后不要北桥的出现了,每个CPU一个MC,这下爽了,每个CPU真正是并行访问了,不过前提也是CPU只访问自己的内存还差不多,访问别人的内存….呵呵,于是有了NUMA因子2,应该就是评价访问CPU外内存的代价的指标3

4.2 RAM类型

SRAM和DRAM一个静态的一个动态的。然后,觉得我需要重新找下数电书看下。但是手边没有数电书,不过,SRAM的稳定不易失。DRAM的不稳定,因为用的电容,不过电容会漏电,动态的图还是比较有爱的,不像静态的,根本就是不同的世界观设定,存的时候就往电容里充电,当然大电容也无所谓的了,可惜啊,这里是计算机电路,不是激光炮塔的辅助电容,要小啊小,只能存几万个电子,作者知道读者会没有概念,所以说了若干兆欧电阻也会很快跑光。 所以,DRAM要刷新,每64ms,这么多年了,不知道还是不是这个数字。刷新的时候不能动哦,而且,电容都是慢慢跑出来,所以读数据要信号放大器,而电容充放电也都需要时间,都是有延时的,所以电路图不是完美的数电专用两道杠图,而是弧线,竟然还给了时间公式,给个图不就行了,作者真认真,程序员是只看图不看公式的。 DRAM也是有好处的,最大的好处是尺寸小、结构简单、成本低,我怎么感觉这是唯一的好处呢?竟然就靠这一个好处满地发芽,果然,人就靠三板斧就够用了。

4.2.1 DRAM访问

内存访问过程自然是虚拟地址->物理地址->内存数据,物理地址通过address line4的形式传递给内存,4G内存有232的AL,所以要被重新编码成为这么多AL的一小部分。传递的地址首先要被多路分配[fn:5],一个N的AL会有输出为2N行。这些输出才用来定位内存。 然后说,内存量要是上去了,这种直接的法子没法用,一个1Gbit容量的,需要30AL和230行。反正我就是理解不能,还是看图吧。 内存组织成行和列,为什么呢?因为这样方便,不用超大的多路分配。我想想啊,就是一维数组和二维数组的区别,如果是16个元素,一维就要16条线来索引每个元组,二维呢,4×4就可以,每个维度4条线。这样就是16比8的线,差距还不大,换成232就出来了一个是232,一个是216+216,所以说,小内存一维直接处理还可以,大了就要增加维度了。要是四维呢?210,是不是维度可以无限增加下去呢?到32维就是…?5 后面还说了扩展性的问题,30根地址线连接到每个RAM芯片也不行,因为针脚会变得很多,解决可扩展问题用的是地址线复用。

4.2.2 总结

  • SRAM和DRAM的成本平衡
  • 存储单元都要被单独选择来使用
  • 地址线数目影响MC、主板、DRAM模块和DRAM芯片成本
  • 读写的时候都要耗费时间的,因为电容的原因

4.3 DRAM访问细节

上节介绍说明了,地址要被复用,节约针脚。访问内存也需要充放电时间,还要刷新。说的都是同步DRAM。统一一个时钟来保持频率,也就是前端总线,但是FSB不是直接的时钟频率,因为可以很多倍,所以200的可以宣传是800.传输速度是频率×传输的位数,不过还有更多闲置的时间用于协商。

4.3.1

看图先,先传RAS ,tRCD时间后再传CAS,地址则在这段时间同时传输。然后就要等会,叫做CL时延,之后就开始传数据,但是如果每次只传一个字太浪费,最好每次都把缓存里面的线填满6,同时还可以不用再重新发RAS直接发CAS,这样就是连续读取内存,少了之前的那些通讯开销。双通道的自然是双倍。

4.3.2 预充电与激活

RAS信号之前还要先锁定当前行然后对新行充电。要那么一段时间,结果就是,又占用了时间,不过预充电的一部分时间可以和数据传输并行,因为是两个不同行7。实际情况可以更加夸张还有tRAS的延时,预充电不是立即执行。 DDR模块的数据表示方法w-z-y-T,比如2-3-2-9-T1

  • w 2 CAS延时(CL)
  • x 3 RAS-to-CAS延时(t RCD)
  • y 2 预充电时间(t RP)
  • z 8 激活到预充电时间(t RAS)
  • T T1 命令速率

4.3.3 重充电

DRAM必须保持刷新,也是按照行刷新,要是程序读的数据那行正好在刷新,那就中奖了8

4.3.4 内存类型

SDR SDRAM,数据传输和内存总线频率一样。速度比较慢,要提速只能提高频率,但是功耗会增加,同时也需要增加电压,进一步增加功耗。『功率= 动态电容×电压2×频率 』 DDR SDRAM(DDR1),每周期可以传输两次数据,上升下降都可以传输数据,引入缓冲区。 DDR2, 总线频率加倍,所以带宽也加倍。但是内存的芯片频率还是保持单倍不变,只是利用缓冲区的频率加倍,每次多读数据到缓存区。最后还要算上每周期的两次数据传输。最后就是阵列频率*4。 DDR3,频率成为4倍,但是内部频率依然是一倍,还是依靠缓存区。算上两次数据传输,就是阵列频率×8。

看了看,内存阵列的频率基本没有变化,都是依靠缓存区的频率加倍来提升。速度快了,但是针脚貌似也增加了9,并行化就难做,连线要差不多一样长10,针脚越多就越不好设计,竟然还有个更大的问题,总线上东西连多了信号会有变化。北桥不好保证内存双通道的并行,需要依靠外部内存控制器。 解决方法:处理器加入内存控制器,或者NUMA架构。 Intel使用什么全缓冲DRAM(FB-DRAM)技术。不用并行总线,而是使用串行总线,频率可以更高,消除串行的缺点还可以增加带宽。改用串行后

  1. 每个通道可以连接更多模块
  2. 北桥内存控制器可以使用更多通道
  3. 串行总线可以全双工(两条线)
  4. 实现另外一个总线也容易,每方向也就两根线11,就可以增加速度了。

FB的有69针脚,也可以连接更多到总线上。北桥可以6通道,布线简单。总结比较给了个表,就是针脚小了,通道多了,还可以多连设备,设计上也简单容易。这难道是个万金油,也说说缺点啊。

4.3.5 总结

终于到总结了,那就是DRAM的速度在现在的CPU面前就是渣,给的core2的差距是11倍差距,内存总线一个周期CPU要等11个周期,所以这个是数量级的差别。 当然,极限情况下,DRAM可以很快,但是需要连续的串行访问数据,如果不连续,就要预充电再加上那一堆延时。预读取可以改善一些性能问题,处理完了就要写入的数据可以直接写入,因为下一轮要读取的东西都已经预读取了,不存在读写冲突了。

4.4 主存的其他用户

除了CPU,访问内存的还有一堆东西。DMA的东西,USB的东西。DMA会和CPU竞争内存访问的总线。 还有利用内存做显存的,这说的好像是我的Pro啊,这个自然也是和CPU竞争内存总线的。

5 好大一个坑

下面就进入无中文版参考范围,此坑够大够深,我一定是吃饱了。

Footnotes:

1

这个是个什么东西?

2

原来NUMA就是这里出来的。

3

那末,what if出来了…每个CPU都和每个内存连起来呢?完全图一样的布线,而且估计CPU并行的问题还不太好处理,内存可以自带内存锁?

4

这又是个什么东西?简称AL吧。

5

这里先歇歇,有问题。

6

这里又是什么东西?不是总线填满么?

7

同行怎么办呢?同行连续读多了是不是电也会漏光呢?

8

可不可以用冗余内存,错开刷新时间来避免?不过这个成本有点高,小概率事件投入那么多。

9

这是为什么?

10

应该是因为电流速度太慢了,要保持电流的电位同时到达,所以,还是换成光实在,宇宙极限了,要再快点只能交给造物主了。

11

应该是指实现后每条方向总共2条线。