Linux内存系列 1概览
0 介绍
在早期电脑组成都是非常简单的。系统的各种组件,如CPU,内存,大容量存储和网络接口都是一起开发的,因此性能非常平衡。例如,内存和网络接口在提供数据方面速度不如CPU高。
一旦计算机的基本结构稳定下来并且硬件开发者将精力集中在优化单个子系统上,这种情况就会发生改变。然后计算机某些组件的性能就变得大幅落后,瓶颈就出现了。对于大型存储和内存子系统尤其如此,出于成本的原因,相对于其他组件而言,其改进速度更慢。
大规模存储的缓慢时间主要通过使用软件技术来解决:操作系统在主内存中保存最常使用(并且最有可能被使用)的数据,其可以比硬盘更快的速度访问数据。高速缓存存储已添加到存储设备本身,因此无需更改操作系统即可提高性能。{ 但是,需要进行一些调整,以确保使用存储设备的缓存时的数据完整性。}为了本文的目的,我们将不再详细介绍大容量存储访问的软件优化。
与存储子系统不同,将主内存作为瓶颈进行移除已证明要困难得多,几乎所有的解决方案都需要对硬件进行更改。今天这些变化主要有以下几种形式:
-
RAM硬件设计(速度和并行性)。
-
内存控制器设计。
-
CPU缓存。
-
设备的直接内存访问(DMA)。
大多数情况下,本文将讨论CPU高速缓存(cache)以及内存控制器设计的一些影响。在探索这些主题的过程中,我们也一并探索DMA并将其纳入更大的构图。但是,我们将从当前的商品硬件设计概述开始。这是了解有效使用内存子系统的问题和局限性的先决条件。我们还将详细了解不同类型的RAM,并说明为什么这些差异仍然存在。
此文绝不是全面的,也不是最终的。它仅限于商品硬件,并进一步限于该硬件的子集。此外,为了本文的目标,将对许多主题进行足够详细的讨论。对于这些主题,建议读者找到更详细的文档。
当涉及到特定于操作系统的细节和解决方案时,该文本仅描述Linux。任何时候它都不会包含任何有关其他操作系统的信息。作者没有兴趣讨论对其他操作系统的影响。如果读者认为他/她必须使用不同的操作系统,他们必须去他们的供应商并要求他们编写与此类似的文档。
开始前最后一条要注意的:本文多次出现“通常”和其他类似限定符。这里讨论的技术存在于现实世界中的许多变体中,本文仅讨论最常见的主流版本。很少有关于这项技术的绝对声明,因此是限定词。
0.1文章结构
本文主要针对软件开发人员。它没有涉及硬件的足够技术细节,因此无法用于面向硬件的读者。但在讲述关于开发者如何实践之前,必须做好大量的基础工作。
为此,系列2以技术细节描述了随机存取存储器(RAM)。本部分的内容很好理解,但不是绝对关键,能够理解后面的部分。在需要内容的地方添加对该部分的适当引用,以便焦虑的读者可以首先跳过本节的大部分内容。
系列3介绍了CPU缓存行为的许多细节。已经使用图表来让文字不会像前面那样干燥。这些内容对于理解文档的其他部分至关重要。系列4简要介绍了虚拟内存是如何实现的。这也是后面内容的基础。
系列5详细介绍了非统一内存访问(NUMA)系统。
系列6是核心部分。它汇集了所有前面部分的信息,并为程序员提供了关于如何编写在各种情况下表现良好的代码的建议。非常不耐烦的读者可以从本节开始,如有必要,可以回到前面的章节来清楚了解底层技术的知识。
系列7介绍了可以帮助程序员做得更好的工具。即使对该技术有完整的理解,在非平凡软件项目中的问题仍然不明显。一些工具是必要的。
在系列8中,我们最终给出了一个可以在不久的将来预期的技术展望,或者可能只是很好的技术展望。
1 当今的商品型硬件
了解商品硬件非常重要,因为专用硬件正在退出。现阶段的扩展通常是水平的,而不是垂直的,这意味着现在使用许多小型的,互连的商品计算机,而不是几个非常大的和特别快速(和昂贵的)系统,前者性价比更高。这是因为快速且廉价的网络硬件广泛可用。大型专业系统仍然存在,而且这些系统仍然提供了商业机会,但整体市场已经被商品硬件市场所笼罩。到2007年为止,Red Hat预计,对于未来的产品,大多数数据中心的“标准构建模块”将是一台带有四个插槽的计算机,每个插槽都装有一个四核CPU,就Intel CPU而言,超线程。 {超线程技术使单个处理器内核可以用于两个或更多并发执行,只需要一些额外的硬件。}这意味着数据中心的标准系统将拥有多达64个虚拟处理器。更大的机器将得到支持,但四插槽四核CPU内核案例目前被认为是最佳选择,大多数优化都针对这类机器。
商品计算机的结构存在很大差异。也就是说,我们将通过关注最重要的差异来覆盖90%以上的这种硬件。请注意,这些技术细节往往会发生很大的变化,因此建议读者考虑撰写本文的日期。(2007年9月21日)
多年来,个人电脑和小型服务器在芯片组上标准化,包括两部分:北桥和南桥。图1.1显示了这个结构。所有的CPU(前面的例子中有两个,但可以多一些)通过一条公共总线(前端总线,FSB
)连接到北桥。除此之外,北桥还包含内存控制器,其实现决定了用于计算机的RAM芯片的类型。不同类型的RAM,如DRAM
,Rambus
和SDRAM
,需要不同的存储器控制器。
要连接所有其他系统设备,北桥必须与南桥进行通信。南桥通常被称为I / O桥
,通过各种不同的总线处理与设备的通信。今天,PCI
,PCI Express
,SATA
和USB总线
是最重要的,但南桥还支持PATA
,IEEE 1394
,串行和并行端口。较旧的系统具有连接到北桥的AGP插槽
。这是由于北桥和南桥之间的快速连接不充分带来的性能原因。但是,今天·插槽都连接到南桥。
这样的体系结构带来了这样一些问题:
-
所有从一个CPU到另一个CPU的数据通信都必须通过与北桥通信的总线。
-
所有与RAM的通信都必须通过北桥。
-
RAM只有一个端口。 {我们不会在本文中讨论多端口RAM,因为这种类型的RAM在商用硬件中不存在,至少在程序员无法访问的地方是这样。它可以在专门的硬件中找到,例如依赖最快速度的网络路由器。}
-
CPU和连接到南桥的设备之间的通信路由通过北桥。
这种设计中立即出现了几个瓶颈。一个瓶颈是与设备访问RAM有关。在PC的初期,与任何一个桥上的设备进行的任何通信都必须通过CPU,这会对整体系统性能产生负面影响。为了解决这个问题,一些设备可以直接访问内存(DMA)。 DMA
允许设备在北桥的帮助下直接在RAM中存储和接收数据,而无需CPU的干预(及其固有性能成本)。今天连接到任何总线的所有高性能设备都可以使用DMA。虽然这大大降低了CPU的工作量,但它也会造成北桥带宽争用,因为DMA请求会与来自CPU的RAM访问竞争。因此,这个问题必须考虑在内。
第二个瓶颈涉及到从北桥到RAM的总线。总线的确切细节取决于部署的内存类型。在较旧的系统中,所有RAM芯片只有一条总线,因此不可能并行访问。最近的RAM类型需要两条独立的总线(或者称为DDR2
的通道,见图1.8),这会使可用带宽增加一倍。北桥交错跨越通道的存储器访问。最近的内存技术(比如FB-DRAM)增加了更多的通道。
在可用带宽有限的情况下,以减少延迟的方式安排内存访问非常重要。正如我们将看到的,尽管使用了CPU缓存,但处理器速度更快,并且必须等待访问内存。如果多个超线程,内核或处理器同时访问内存,则内存访问的等待时间甚至更长。 DMA操作也是如此。
但是,访问内存比并发更多。访问模式本身也极大地影响了内存子系统的性能,尤其是对于多个内存通道。有关RAM访问模式的更多详细信息,请参阅第1.2节。
在一些更昂贵的系统上,北桥实际上并不包含内存控制器。相反,北桥可以连接到许多外部内存控制器(在下面的例子中,其中四个)。这种架构的优点是存在多于一条内存总线,因此总带宽增加。这种设计也支持更多的内存。并发内存访问模式通过同时访问不同的内存条来减少延迟。当多个处理器直接连接到北桥时,尤其如此,如图1.2所示。对于这样的设计,主要限制是北桥的内部带宽,这对于这种架构(来自英特尔)来说是惊人的。 {为了完整起见,应该提及的是,这种内存控制器布置可以用于其他目的,例如与内存热插拔结合使用的“内存RAID”。}
使用多个外部存储器控制器不是增加内存带宽的唯一方法。另一个日益流行的方式是将内存控制器集成到CPU中,并将内存连接到每个CPU。这种架构受到基于AMD Opteron处理器的SMP系统的欢迎。图1.3显示了这样一个系统。英特尔将支持从Nehalem处理器开始的通用系统接口(CSI);这基本上是一样的:一个集成的内存控制器,每个处理器都有本地内存的可能性。有了像这样的架构,可以使用的处理器数量尽可能多。在四核CPU上,内存带宽增加了四倍,而无需复杂的带宽巨大的北桥。将内存控制器集成到CPU中有一些额外的优点;我们不会在这里深入研究这项技术。
这种架构也有缺点。首先,因为机器仍然必须使系统的所有内存都可以被所有处理器访问,所以内存不再统一(因此,名称为NUMA
- 非统一内存架构 - 用于这样的架构)。本地存储器(连接到处理器的存储器)可以用通常的速度访问。当访问连接到另一个处理器的内存时,情况会有所不同。在这种情况下,必须使用处理器之间的互连interconnect
。要从CPU1访问连接到CPU2的内存,需要通过一个interconnect
进行通信。当相同的CPU访问连接到CPU4的内存时,必须跨越两个interconnect
。
每个这样的通信都有相关的成本。当我们描述访问远程内存所需的额外时间时,我们讨论numa facor
。图1.3中的示例体系结构对于每个CPU有两个级别:紧邻的CPU和两个interconnect
距离的CPU。随着更复杂的机器数量的水平可以显着增长。也有机器体系结构(例如IBM的x445和SGI的Altix系列),其中有多种类型的连接。 CPU被组织成节点;在一个节点内访问内存的时间可能是统一的,或者只有很小的numa factor
。但是,节点之间的连接可能非常昂贵,而numa factor
可能相当高。
商品NUMA机器今天存在,并且可能在未来发挥更大的作用。预计从2008年底开始,每台SMP机器都将使用NUMA。与NUMA相关的成本使得识别程序何时在NUMA机器上运行非常重要。在第5节中,我们将讨论更多的机器体系结构和Linux内核为这些程序提供的一些技术。
除了本节其余部分描述的技术细节外,还有几个影响RAM性能的其他因素。它们不受软件控制,这就是为什么它们不在本节中讨论的原因。有兴趣的读者可以在第2.1节中了解一些这些因素。他们只是需要更全面地了解RAM技术,并可能在购买计算机时做出更好的决策。
以下两节讨论了门级的硬件细节和内存控制器与DRAM芯片之间的访问协议。程序员可能会发现这些信息有启发性,因为这些细节解释了为什么RAM访问按照它的方式工作。不过,这是可选的知识,读者急于想到与日常生活更直接相关的主题可以跳到1.2.5节。
1.1 RAM类型
多年来RAM的种类很多,每种类型的RAM都有所不同,有时甚至显着不同。今天的老年人真的只对历史学家感兴趣。我们不会探讨这些细节。相反,我们将专注于现代RAM类型;我们只会刮目相看,探索一些内核或应用程序开发人员通过其性能特征可见的细节。
第一个有趣的细节集中在为什么在同一台机器上有不同类型的RAM的问题上。更具体地说,为什么同时存在静态RAM(SRAM {在其他情况下,SRAM可能意味着“同步RAM”)和动态RAM(DRAM))。前者速度更快,并提供相同的功能。为什么不是机器SRAM中的所有RAM?正如人们所预料的那样,答案是成本。与DRAM相比,生产和使用SRAM要昂贵得多。这两个成本因素都很重要,第二个越来越重要。为了理解这些差异,我们考察了SRAM和DRAM的一些存储实现。
在本节的其余部分中,我们将讨论RAM的实现的一些底层细节。我们将尽可能降低细节水平。为此,我们将在“逻辑级”讨论信号,而不是硬件设计人员必须使用的级别。对于我们的目的而言,这种细节水平是不必要的。
1.1.1 静态RAM
图1.4显示了一个6晶体管SRAM单元的结构。该单元的核心由形成两个交叉耦合反相器的四个晶体管M1至M4形成。它们有两个稳定状态,分别代表0和1。只要Vdd电源可用,状态就会稳定。
如果需要访问单元的状态,则字存取线WL被提升。这使得单元格的状态立即可用于BL和BL'上的读取。如果单元状态必须被覆盖,则BL和BL线首先被设置为期望值,然后WL被提升。由于外部驱动器比四个晶体管(M1至M4)更强,这允许旧状态被覆盖。
请参阅[sramwiki]以获取有关单元格工作方式的更详细说明。对于下面的讨论,重要的是要注意这一点
-
一个电池需要六个晶体管。有四个晶体管的变体,但它们有缺点。
-
保持电池的状态需要恒定的功率。
-
一旦单词存取线WL升高,单元状态几乎立即可用于读取。该信号与其他晶体管控制的信号一样是矩形的(在两个二进制状态之间快速变化)。
-
电池状态稳定,不需要更新周期。
还有其他更慢,耗电更少的SRAM形式可用,但由于我们正在查看快速RAM,因此这些内容并不令人感兴趣。这些缓慢的变体主要是有趣的,因为它们的接口更简单,因此它们比动态RAM更容易在系统中使用。
1.1.2 动态RAM
动态RAM在结构上比静态RAM简单得多。 图1.5显示了通常DRAM单元设计的结构。 它由一个晶体管和一个电容组成。 这种复杂性的巨大差异意味着它的功能与静态RAM非常不同。动态RAM单元在电容器C中保持其状态。晶体管M用于保护对状态的访问。要读取存取线AL的单元状态,这或者导致电流在数据线DL上流动,或者不依赖于电容器中的电荷。为了写入单元,数据线DL被适当地设置,然后将AL上升足够长的时间以充电或放电电容器。
动态RAM的设计有许多复杂性。使用电容器意味着读取电池使电容器放电。该过程不能无限重复,电容器必须在某个时刻进行充电。更糟糕的是,为了容纳大量的电池(具有109个或更多电池的芯片现在普遍存在),电容器的容量必须很低(在毫微微法拉范围内或更低)。一个完全充电的电容器可容纳几十个数千个电子。即使电容器的电阻很高(几个兆欧姆),它也只需要很短的时间来消散电容。这个问题被称为“泄漏”。
这种泄漏是DRAM单元必须不断刷新的原因。对于大多数DRAM芯片来说,这些刷新必须每64ms发生一次。在刷新周期期间,不可能访问存储器。对于某些工作负载,这个开销可能会导致50%的内存访问失败(请参见[highperfdram])。
微小费用导致的第二个问题是从单元中读取的信息不能直接使用。数据线必须连接到一个读出放大器,该读出放大器可以在仍然必须计数为1的整个电荷范围内区分存储的0或1。
第三个问题是充电和放电电容不是瞬时的。由读出放大器接收到的信号不是矩形的,因此必须使用关于单元输出何时可用的保守估计。充电和放电电容的公式是简单的方法也有其优点。 主要优势是尺寸。 一个DRAM单元所需的芯片空间比SRAM单元小很多倍。 对于维持状态的晶体管,SRAM单元也需要单独的电源。 DRAM单元的结构也更简单和更规则,这意味着将它们中的许多封装在一个芯片上更简单。
总体而言,成本差异(相当戏剧性)胜出。 除了专用硬件 - 例如网络路由器,我们必须与基于DRAM的主存储器共存。 这对程序员有巨大的影响,我们将在本文的其余部分讨论。 但首先我们需要研究DRAM单元实际使用的一些细节。
1.1.3 DRAM访问
程序使用虚拟地址选择内存位置。处理器将其转换为物理地址,最后存储器控制器选择与该地址对应的RAM芯片。为了选择RAM芯片上的单个存储单元,物理地址的一部分以许多地址线的形式传递。
从存储器控制器单独寻址存储单元是完全不切实际的:4GB的RAM需要232个地址线。相反,地址通过使用一组较小的地址线编码为二进制数字。以这种方式传递给DRAM芯片的地址必须首先被解复用。具有N个地址线的解复用器将具有2N个输出线。这些输出线可用于选择存储单元。对于小容量的芯片,使用这种直接方法并不是什么大问题。
但是如果细胞数量增加,这种方法不再适用。 1Gbit的芯片{我讨厌那些SI前缀。对我来说千兆位总是230而不是109位。容量需要30条地址线和230条选择线。当不牺牲速度时,解复用器的大小随着输入线数目呈指数增长。除了解复用器的复杂性(大小和时间)之外,用于30个地址线的解复用器还需要大量的芯片空间。更重要的是,在地址线上同步传送30个脉冲比传送“仅”15个脉冲要困难得多。较少的线路必须按照相同的长度或适当的时间布置。 {像DDR3这样的现代DRAM类型可以自动调整时序,但对于什么可以容忍有限制。}图1.7显示了一个非常高的DRAM芯片。 DRAM单元按行和列组织。它们都可以排成一排,但DRAM芯片需要一个巨大的解复用器。使用阵列方法,设计可以通过一个解复用器和一个大小一半的复用器来获得。 {多路复用器和多路解复用器是等效的,这里的多路复用器需要在写入时作为多路分解器工作。所以我们会从现在开始放弃差异化。}这是所有战线的巨大节约。在这个例子中,通过行地址选择(RAS)解复用器的地址线a0和a1选择整行单元的地址线。读取时,所有单元的内容因此可用于列地址选择(CAS){名称上的行表示该信号被否定}多路复用器。基于地址线a2和a3,一列的内容然后可用于DRAM芯片的数据管脚。这在多个DRAM芯片上并行发生多次,以产生对应于数据总线宽度的总位数。
为了写入,新的单元值被放置在数据总线上,并且当使用RAS和CAS选择单元时,它被存储在单元中。一个非常简单的设计。实际上 - 显然 - 还有更多的并发症。在数据总线上可以读取数据之前,需要规定信号后有多少延迟。如前一节所述,电容器不会立即卸载。来自细胞的信号非常弱,需要放大。为了写入,必须指定在RAS和CAS完成后,数据必须在总线上可用多长时间才能成功地将新值存储在单元中(再次,电容器不会立即填充或放入)。这些时序常数对于DRAM芯片的性能至关重要。我们将在下一节讨论这个问题。
二次可扩展性问题在于,每个RAM芯片有30条地址线是不可行的。芯片的引脚是宝贵的资源。数据必须尽可能平行地传送(例如,以64位批量),这是“坏”的。内存控制器必须能够访问每个RAM模块(RAM芯片的集合)。如果出于性能原因需要并行访问多个RAM模块,并且每个RAM模块需要自己的一组30个或更多的地址线,则对于8个RAM模块,存储器控制器需要具有高达240+个引脚,仅用于地址处理。
为了应对这些二次可扩展性问题,DRAM芯片长期以来对地址本身进行了多路复用。这意味着地址分为两部分。第一部分由图1.7中例子中的地址位a0和a1组成)选择该行。此选择保持有效,直到撤销。然后第二部分地址位a2和a3选择列。关键的区别是只需要两条外部地址线。需要更多的线路来指示RAS和CAS信号何时可用,但是将地址线数量减半的代价很小。不过,这种地址复用会带来一系列问题。我们将在2.2节讨论它们。
1.1.4 结论
如果本节中的细节有点过分,请不要担心。这部分重要的内容是:
-
有理由不是所有的内存都是SRAM
-
存储单元需要单独选择使用
-
地址线的数量直接负责存储器控制器,主板,DRAM模块和DRAM芯片的成本
-
在读取或写入操作的结果可用之前需要一段时间
以下部分将详细介绍访问DRAM内存的实际过程。我们不会详细讨论访问SRAM的细节,这通常是直接解决的。这发生在速度上,因为SRAM存储器的大小有限。 SRAM目前在CPU高速缓存和片上模块中使用,这些连接很小并且完全在CPU设计人员的控制之下。 CPU缓存是我们稍后讨论的一个话题,但我们需要知道的一点是,SRAM单元具有一定的最大速度,这取决于花费在SRAM上的工作量。速度可以从仅比CPU内核略慢的速度慢一个或两个数量级。
1.2 DRAM访问的技术细节
在介绍DRAM的章节中,我们看到DRAM芯片复用地址以节省资源。我们还看到,访问DRAM单元需要时间,因为那些单元中的电容器不会立即放电以产生稳定的信号;我们也看到DRAM单元必须刷新。现在是时候把所有这些放在一起,看看所有这些因素如何决定DRAM访问如何发生。
我们将专注于当前的技术;我们不会讨论异步DRAM及其变体,因为它们不再相关。对此主题感兴趣的读者可以参考[highperfdram]和[arstechtwo]。即使该技术没有过时,我们也不会谈论Rambus DRAM(RDRAM)。它只是没有广泛用于系统内存。我们将专注于同步DRAM(SDRAM)及其后续双倍数据速率DRAM(DDR)。
顾名思义,同步DRAM相对于时间源工作。存储器控制器提供一个时钟,其频率决定了前端总线(FSB) - DRAM芯片使用的存储器控制器接口的速度。截至撰写本文时,800MHz,1,066MHz或甚至1,333MHz的频率可用于下一代的更高频率(1,600MHz)。这并不意味着公共汽车上使用的频率实际上是这么高。相反,今天的公共汽车是双泵或四泵,这意味着数据每个周期运输两到四次。更高的数字销售,所以制造商喜欢宣传四路泵浦200MHz总线作为“有效的”800MHz总线。
对于今天的SDRAM,每个数据传输由64位组成 - 8个字节。因此外频的传输速率是8字节乘以有效总线频率(四抽200MHz总线为6.4GB / s)。这听起来像很多,但它是爆发速度,最高速度永远不会超过。正如我们现在看到的,与RAM模块交谈的协议在没有数据可以传输时会有很多停机时间。正是这种停机时间,我们必须了解并尽量减少以达到最佳性能。
1.2.1 读访问协议
图1.8显示了DRAM模块的一些连接器的活动,这种连接器发生在三个不同颜色的阶段。像往常一样,时间从左到右流动。很多细节都被忽略了。这里我们只讨论总线时钟,RAS和CAS信号以及地址和数据总线。读周期从存储器控制器开始,使地址总线上的行地址可用,并降低RAS信号。所有信号都在时钟(CLK)的上升沿读取,因此只要信号在读取时是稳定的,信号是不是完全平方即可。设置行地址将导致RAM芯片开始锁定寻址的行。
CAS信号可以在tRCD(RAS到CAS延迟)时钟周期后发送。然后通过在地址总线上提供列地址并降低CAS行来发送列地址。在这里,我们可以看到地址的两部分(或多或少的一半,没有别的意义)可以通过相同的地址总线传输。
现在寻址完成并且可以传输数据。 RAM芯片需要一些时间来为此做准备。延迟通常称为CAS延迟(CL)。在图1.8中,CAS延迟为2.它可以更高或更低,这取决于内存控制器,主板和DRAM模块的质量。等待时间也可以具有一半的值。在CL = 2.5时,第一个数据将在蓝色区域的第一个下降侧面可用。
通过所有这些准备工作来获取数据,只传输一个数据字将是浪费。这就是DRAM模块允许内存控制器指定要传输多少数据的原因。通常选择2,4或8个字。这样可以在没有新的RAS / CAS序列的情况下填充高速缓存中的整个行。内存控制器也可以发送新的CAS信号而不重置行选择。通过这种方式,连续的存储器地址可以读取或写入速度明显更快,因为不必发送RAS信号,也不必关闭该行(见下文)。保持行“打开”是内存控制器必须决定的。投机性地将其一直开放在现实世界的应用程序中有缺点(参见[highperfdram])。发送新的CAS信号只受RAM模块的命令速率限制(通常指定为Tx,其中x为1或2的值;对于每个周期接受新命令的高性能DRAM模块,其值为1)。
在这个例子中,SDRAM每个周期吐出一个字。这是第一代所做的。 DDR能够在每个周期传输两个字。这减少了传输时间,但不会改变延迟。原则上,DDR2的工作原理虽然在实践中看起来不同。这里没有必要深入细节。只要注意DDR2可以更快,更便宜,更可靠并且更节能(参见[ddrtwo]以获取更多信息)就足够了。
1.2.2 预充电和激活
图1.8并未涵盖整个周期。 它只显示了访问DRAM的整个周期的一部分。 在发送新的RAS信号之前,必须停用当前锁存的行,并且必须对新行进行预充电。 我们可以把注意力集中在用明确命令完成的情况。 对协议有改进,在某些情况下,可以避免这一额外步骤。 不过,预充电引起的延迟仍然会影响操作。图1.9显示了从一个CAS信号开始到另一行CAS信号的活动。第一个CAS信号请求的数据在CL周期之后可以像以前那样获得。在这个例子中,需要两个字,在简单的SDRAM上需要两个周期来传输。或者,想象一下DDR芯片上的四个字。
即使在命令率为1的DRAM模块上,预充电命令也不能立即发出。只要传输数据就需要等待。在这种情况下需要两个周期。这恰好与CL相同,但这只是巧合。预充电信号没有专用线;相反,一些实现通过同时降低写使能(WE)和RAS线来发出它。这种组合本身没有有用的含义(详见编码细节[micronddr])。
一旦发出预充电命令,它将花费tRP(行预充电时间)周期,直到可以选择行。在图1.9中,大部分时间(用紫色表示)与存储器传输(浅蓝色)重叠。这很好!但tRP大于传输时间,因此下一个RAS信号在一个周期内停顿。
如果我们继续图表中的时间线,我们会发现下一次数据传输发生在前一次停止后的5个周期。这意味着数据总线仅使用七个周期中的两个周期。将其与FSB速度相乘,800MHz总线的理论值6.4GB / s变为1.8GB / s。这是不好的,必须避免。第6节中描述的技术有助于提高这个数字。但程序员通常必须做她的份额。
SDRAM模块还有一个我们没有讨论过的时序值。在图1.9中,预充电命令仅受数据传输时间的限制。另一个限制是SDRAM模块需要一段时间后才能对另一行进行预充电(表示为tRAS)。这个数字通常非常高,大约是tRP值的两倍或三倍。如果在RAS信号之后只有一个CAS信号,并且数据传输在几个周期内完成,则这是一个问题。假定在图1.9中,初始CAS信号直接由RAS信号开始,tRAS为8个周期。然后,由于tRCD,CL和tRP的总和(因为它大于数据传输时间)只有7个周期,因此预充电命令必须延迟一个附加周期。
DDR模块通常使用特殊的符号:w-x-y-z-T来描述。例如:2-3-2-8-T1。意即:w 2 CAS潜伏期(CL)x 3 RAS到CAS延迟(tRCD)y 2 RAS预充电(tRP)z 8有源到预充电延迟(tRAS)T T1命令速率
还有许多其他的时序常量会影响命令发出和处理的方式。不过,这五个常量实际上足以确定模块的性能。
知道使用的计算机能够解释某些测量的这些信息有时很有用。购买计算机时了解这些细节绝对有用,因为它们与FSB和SDRAM模块速度一起是决定计算机速度的最重要因素。
非常冒险的读者也可以尝试调整系统。有时BIOS允许更改一些或全部这些值。 SDRAM模块具有可设置这些值的可编程寄存器。通常BIOS会选择最佳的默认值。如果RAM模块的质量较高,则可能会减少一个或另一个延迟,而不会影响计算机的稳定性。遍布互联网的众多超频网站为此提供了充足的文档。尽管你自己承担风险,但并没有说你没有受到警告。
1.2.3 充电
谈到DRAM访问时,一个最被忽视的话题就是充电。如第2.1.2节所述,DRAM单元必须不断更新。对于系统的其他部分来说,这并不完全透明。有时当一行{行是粒度时,尽管[highperfdram]和其他文献说(见[micronddr]),这种情况发生了。}}被重新充电时,不可能访问。 [highperfdram]的研究发现“令人惊讶的是,DRAM刷新组织可以显着影响性能”。
根据JEDEC规范,每个DRAM单元必须每64ms更新一次。如果一个DRAM阵列有8,192行,这意味着内存控制器必须平均每7.8125μs发布一次刷新命令(刷新命令可以排队,因此实际上两个请求之间的最大间隔可以更高)。内存控制器有责任计划刷新命令。 DRAM模块跟踪最后一次刷新的行的地址,并自动增加每个新请求的地址计数器。
程序员在刷新命令时可以做的事情并不多。但在解释测量时,牢记DRAM部分的生命周期非常重要。如果必须从当前正在刷新的行中检索关键词,则处理器可能会停滞很长时间。每次刷新需要多长时间取决于DRAM模块。
1.2.4 内存类型
值得花费一些时间在当前和即将使用的当前内存类型上。 我们将从SDR(单数据速率)SDRAM开始,因为它们是DDR(双倍数据速率)SDRAM的基础。 特别提款权非常简单。 存储单元和数据传输速率是相同的。SDR和DDR1之间的区别在于,如图1.11所示,并且从名称中可以看出,每个周期传输的数据量是数据量的两倍。即,DDR1芯片在上升沿和下降沿传输数据。这有时被称为“双泵”公交车。为了在不增加单元阵列频率的情况下实现这一点,必须引入缓冲器。该缓冲器每个数据线保存两位。这又要求在图1.7的单元阵列中,数据总线由两条线组成。实现这一点很简单:只有两个DRAM单元使用相同的列地址并且可以并行访问它们。对单元数组进行更改以实现此目的也很小。
SDR DRAM简单地通过它们的频率而知晓(例如,用于100MHz SDR的PC100)。为了使DDR1 DRAM的声音更好,营销人员不得不提出一个新的方案,因为频率没有变化。他们带有一个名称,其中包含DDR模块(它们具有64位总线)可以承受的传输速率(以字节为单位):
100MHz×64bit×2 = 1600MB / s因此,具有100MHz频率的DDR模块被称为PC1600。 1600> 100的所有营销要求都得到满足;这听起来好多了,虽然改善只是两个因素。 {我会采取两个因素,但我不必喜欢夸大的数字。}为了获得更多的内存技术,DDR2包含了更多的创新。 图1.12中最明显的变化是总线频率加倍。 将频率加倍意味着将带宽加倍。 由于频率倍增对于单元阵列来说并不经济,因此现在要求I / O缓冲器在每个时钟周期中获得四位,然后可以在总线上发送。 这意味着对DDR2模块的更改包括仅使DIMM的I / O缓冲器组件能够以更高的速度运行。 这当然是可能的,不会需要更多的能量,它只是一个微小的组件,而不是整个模块。 营销人员为DDR2提出的名称与DDR1名称相似,只是在计算两个因子的值由四个(我们现在有一个四重抽头总线)的计算值中。 图1.13显示了当前使用的模块的名称。Array Freq. Bus Freq. Data Rate Name(Rate) Name(FSB)133MHz 266MHz 4,256MB/s PC2-4200 DDR2-533166MHz 333MHz 5,312MB/s PC2-5300 DDR2-667200MHz 400MHz 6,400MB/s PC2-6400 DDR2-800250MHz 500MHz 8,000MB/s PC2-8000 DDR2-1000266MHz 533MHz 8,512MB/s PC2-8500 DDR2-1066
命名还有一个转折点。 CPU,主板和DRAM模块使用的FSB速度通过使用有效频率指定。即,它在时钟周期的两侧传输因素,并因此使数量膨胀。因此,具有266MHz总线的133MHz模块具有533MHz的FSB“频率”。
DDR3规范(真正的,而不是显卡中使用的假GDDR3)要求向DDR2过渡时发生更多变化。 DDR2的电压将从1.8V降至1.5V。由于功率消耗方程是使用电压的平方来计算的,所以这仅仅带来了30%的改善。除此之外,还可以减小芯片尺寸以及其他电气方面的进步,DDR3可以在相同的频率下管理功耗的一半。或者,在更高频率下,可以击中相同的功率包络。或者容量增加一倍,可以达到同样的散热效果。
DDR3模块的单元阵列将以外部总线的四分之一速度运行,这需要8位I / O缓冲器,而DDR2则需要4位。原理图见图1.14。由于DDR2技术更成熟,最初DDR3模块的CAS延迟可能稍高。这会导致DDR3仅在频率高于DDR2所能达到的频率时才有用,即使这样,大多数时候带宽比延迟更重要。目前已经有关于可以实现与DDR2相同的CAS延迟的1.3V模块的讨论。无论如何,由于更快的总线而实现更高速度的可能性将超过增加的延迟。
DDR3的一个可能的问题是,对于1600Mb / s或更高的传输速率,每个通道的模块数量可能会减少到一个。在以前的版本中,这个要求适用于所有频率,所以人们可以希望在某些时候对所有频率的要求都会被提升。否则系统的容量将受到严重限制。
图1.15显示了预期的DDR3模块的名称。 JEDEC迄今为止同意前四种类型。鉴于英特尔45纳米处理器的FSB速度为1600Mb / s,超频市场需要1,866Mb / s。在DDR3生命周期结束时,我们可能会看到更多这样的情况。Array Freq. Bus Freq. Data Rate Name(Rate) Name(FSB)100MHz 400MHz 6,400MB/s PC3-6400 DDR3-800133MHz 533MHz 8,512MB/s PC3-8500 DDR3-1066166MHz 667MHz 10,667MB/s PC3-10667 DDR3-1333200MHz 800MHz 12,800MB/s PC3-12800 DDR3-1600233MHz 933MHz 14,933MB/s PC3-14900 DDR3-1866所有的DDR内存都有一个问题:增加的总线频率使得很难创建并行数据总线。 DDR2模块有240个引脚。数据和地址引脚的所有连接必须进行路由,以使它们具有大致相同的长度。更多的问题是,如果多个DDR模块在同一总线上进行菊花链连接,则每个附加模块的信号会越来越失真。 DDR2规范每条总线(又名通道)只允许两个模块,DDR3规范只有一个模块用于高频率。每个通道240个引脚,单个北桥不能合理驱动两个以上的通道。另一种方法是使用外部存储器控制器(如图1.2所示),但这样很昂贵。
这意味着商品主板只能容纳最多四个DDR2或DDR3模块。这个限制严重限制了系统可以拥有的内存量。即使是老式的32位IA-32处理器也可以处理64GB的RAM和内存需求,即使家庭使用也在增长,所以必须做些事情。
一个答案是如第2节所述,将存储器控制器添加到每个处理器中。AMD采用Opteron产品线,英特尔将采用其CSI技术实现。只要处理器能够使用的合理内存量可以连接到单个处理器,这将有所帮助。在某些情况下,情况并非如此,此设置将引入NUMA体系结构及其负面影响。在某些情况下需要另一种解决方案。
英特尔对大型服务器机器的这一问题的答案至少在未来几年被称为全缓冲DRAM(FB-DRAM)。 FB-DRAM模块使用与当今DDR2模块相同的组件,这使得它们的生产成本相对较低。区别在于与内存控制器的连接。取代并行数据总线,FB-DRAM采用串行总线(Rambus DRAM也是如此,而SATA是PATA的后继产品,PCI / AGP则是PCI Express)。串行总线可以以更高的频率驱动,恢复序列化的负面影响,甚至增加带宽。使用串行总线的主要影响是
-
可以使用每个通道更多的模块。
-
每个北桥/内存控制器可以使用更多的通道。
-
串行总线设计为全双工(两条线)。
FB-DRAM模块只有69个引脚,而DDR2则为240。雏菊链式FB-DRAM模块更容易,因为总线的电气效果可以更好地处理。 FB-DRAM规范允许每个通道多达8个DRAM模块。与双通道北桥的连接要求相比,现在可以用更少的引脚驱动6个通道的FB-DRAM:2×240引脚与6×69引脚。每个通道的布线要简单得多,这也有助于降低主板的成本。
对于传统的DRAM模块来说,全双工并行总线的成本过高,重复所有这些线路的成本太高。对于串行线路(即使它们是差分的,如FB-DRAM所要求的),情况并非如此,因此串行总线被设计为全双工,这意味着在某些情况下,带宽理论上可以单独加倍。但它不是唯一一个使用并行机制来增加带宽的地方。由于FB-DRAM控制器可同时运行多达6个通道,因此即使对于使用FB-DRAM的RAM数量较少的系统,也可以增加带宽。如果具有四个模块的DDR2系统具有两个通道,则可以使用普通的FB-DRAM控制器通过四个通道处理相同的容量。串行总线的实际带宽取决于FB-DRAM模块上使用的DDR2(或DDR3)芯片的类型。
我们可以总结这样的优点:
<figure class="md-table-fig" contenteditable="false" cid="n312" mdtype="table" style="box-sizing: border-box; margin: -8px 0px 0px -8px; overflow-x: auto; max-width: calc(100% + 16px); padding: 8px; caret-color: rgb(51, 51, 51); color: rgb(51, 51, 51); font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 16px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;">
DDR2 | FB-DRAM | |
---|---|---|
Pins | 240 | 69 |
Channels | 2 | 6 |
DIMMs/Channel | 2 | 8 |
Max Memory | 16GB | 192GB |
Throughput | ~10GB/s | ~40GB/s |
</figure>
如果使用一个通道上的多个DIMM,FB-DRAM有一些缺点。 信号在链路中的每个DIMM上延迟(尽管最小),这意味着延迟增加。 但对于具有相同频率的相同数量的内存,FB-DRAM始终可能比DDR2和DDR3更快,因为每个通道只需要一个DIMM; 对于大型内存系统,DDR使用商品组件无法解决问题。
1.2.5 结论
本节应该表明,访问DRAM并不是一个任意快的过程。至少与处理器运行的速度相比,或者与它访问寄存器和缓存相比,都是不快的。记住CPU和内存频率之间的差异非常重要。运行在2.933
GHz和1.066
GHz FSB的Intel Core 2处理器的时钟比为11:1(注意:1.066GHz总线是四倍频)。内存总线上的一个周期的每个停顿stall
意味着处理器的11个周期的一个stall
。对于大多数机器而言,实际使用的DRAM速度较慢,因此延长了时间。在接下来的章节讨论到stall
时,请记住这些数字。
读命令的时序图表明,DRAM模块具有高持续数据速率。整个DRAM行可以在不到一个stall
的情况下运输。数据总线可以保持100%。对于DDR模块,这意味着每个周期传输两个64位 字2 64-bit words
。对于DDR2-800模块和两个通道,这意味着12.8GB / s的速率。
但是,除非这样设计,DRAM访问并不总是顺序的。使用非连续存储区域,这意味着需要预充电和新的RAS’信号。然后这就是事情开始变得缓慢以及DRAM模块需要帮助的时候。实际使用该行时,预充电可能发生得越早,并且RAS‘信号发送越小。
硬件和软件预取(参见第6.3节)可用于在时序中创建更多重叠并减少stall
。预取还有助于及时转移内存操作,这样在后续实际需要数据时,竞争就会减少。当一轮中产生的数据必须被存储并且需要读取下一轮所需的数据时,这是一个常见的问题。通过及时移动读取,写入和读取操作不必基本上同时被issue。
1.3 其他主内存的使用者
除了CPU之外,还有其他系统组件可以访问主内存。诸如网络和大容量存储控制器之类的高性能卡无法承担向CPU获取数据或提供给CPU数据的高开销。相反,他们直接从主内存读取或写入数据(直接内存存取,DMA)。在图1.1中,我们可以看到这些卡可以直接与存储器通过南桥和北桥。其他总线,如USB,也需要FSB带宽 - 尽管它们不使用DMA,因为南桥也通过FSB连接到北桥。
虽然DMA确实有利,但这意味着对FSB带宽的竞争更加激烈。在高DMA流量的时候,CPU在等待来自主内存的数据时可能比平时更多地stall
。当然这也有解决办法。使用如图1.3所示的体系结构,可以确保计算在不受DMA影响的节点上使用内存。也可以将一个南桥连接到每个节点,同时分配所有节点的FSB上的负载。有很多的可能性。在第6节中,我们将介绍技术和编程接口,以帮助实现软件中可能的改进。
最后应该提到的是,一些便宜的系统没有独立的专用视频RAM的图形系统。这些系统使用主存储器的一部分作为视频RAM。由于访问视频RAM的频率很高(对于1024 x 768显示器,在60Hz下16bpp,我们说的是94MB / s),系统内存与显卡上的RAM不同,它没有两个端口,这会显着影响系统性能,特别是延迟。当性能优先时,最好忽略这样的系统。它的麻烦大于它的作用。购买这些机器的人知道他们不会获得最佳性能。
Continue to: