13.4 Performance Optimization
现代DRAM内存控制器的性能特性取决于实现特定的DRAM命令和内存事务排序策略。一个DRAM控制器可以被设计成在不考虑性能的情况下最小化复杂性,也可以通过实施积极的DRAM命令和内存事务排序策略来提取内存系统的最大性能。DRAM命令和事务排序策略已经由Briggs等人[2002]、Cuppu等人[1999]、Hur和Lin[2004]、McKee等人[1996]、Lin等人[2001]和Rixner等人[2000]进行了研究。在Briggs等人、Cuppu等人、McKee等人、Lin等人和Rixner等人进行的研究中,考察了各种以DRAM为中心的调度方案。在Hur等人进行的研究中,注意到理想的DRAM调度算法不仅取决于对DRAM内存系统的调度优化,还取决于应用的需求。特别是,将DRAM内存控制器与处理器核心集成到同一硅片上意味着处理器核心可以直接与内存控制器交互,并提供直接反馈来选择最佳的DRAM命令调度算法。
设计高性能的DRAM内存控制器进一步复杂化了,这是因为现代高性能的多线程处理器和多核处理器的出现。虽然多线程被提倡为在现代计算机系统中隐藏内存访问延迟的一种方法,但多线程和多核处理器对DRAM内存系统的净影响是来自多个线程上下文的混合内存请求流干扰了请求模式的行局部性并增加了银行冲突[Lin等人2001]。因此,一个最佳的DRAM控制器设计不仅必须考虑特定DRAM内存系统的特殊性和应用特定的要求,还必须考虑系统中的处理元素的类型和数量。
设计工程师必须考虑的众多设计因素突显了高性能DRAM内存控制器的复杂性。幸运的是,存在一些通用的基本策略,可用于设计高性能的DRAM内存控制器。具体来说,以银行为中心的组织、写缓存和优先考虑先到先服务(Seniors First)的策略适用于许多高性能DRAM控制器,而特定的自适应仲裁算法则是特定DRAM控制器和系统独有的。
13.4.1 Write Caching
许多现代DRAM控制器中采用的一种策略是写缓存策略。写缓存的基本思想是,就延迟而言,写请求通常不是关键的,但读请求通常在延迟方面非常关键。因此,通常希望推迟写请求,允许读请求在写请求之前进行,只要系统的内存排序模型支持这种优化,并且不违反程序的功能正确性。此外,DRAM设备通常设计得不太支持连续的读和写请求。特别是,紧随列写命令之后发生的列读命令通常会因为必须等待DRAM设备内部数据通路的可用性而在传统的DDRx SDRAM设备中产生数据总线切换时间上的大幅惩罚,因为这个数据通路在读和写命令之间共享。
图13.6重现了列读命令在写命令之后的示意图,并显示由于读和写命令之间数据流方向的差异,在连续的列读和写命令之间存在相当大的开销。写缓存策略允许可能对应用性能至关重要的读请求在写请求之前进行,而且当与一种策略结合使用以连续将多个写请求传输到内存系统时,写缓存策略还可以降低读写开销。一个使用写缓存策略的内存控制器是英特尔的i8870系统控制器,它可以缓冲多达8KB的写数据,以优先处理读请求而不是写请求。然而,在实现写缓存的系统中,由于所有待处理的读请求的地址必须与缓存的写地址进行比对,而且内存控制器必须提供一致性保证以确保内存访问排序的正确性,因此可能存在相当大的延迟或硬件复杂性方面的开销。
理解:(1)因为现在系统中master自身操作,对读操作的延迟敏感,对写操作没有那么敏感。
(2)在DRAM操作中,写到读的延迟大于读到写的延迟。很好理解,因为写操作需要将新数据覆盖到储存单元时间比较久。但读到写操作只要保证满足写时序要求即可,只有DQ,DQS方向转换消耗的一个周期的,但往往存在读postamble和写preamble,素以方向切换基本的时间很少。
13.4.2 Request Queue Organizations
为了控制DRAM内存控制器和DRAM设备之间的数据流,现代DRAM内存控制器将内存事务转换为DRAM命令序列。为了便于对这些DRAM命令进行流水线执行,DRAM命令可以放入单个队列或多个队列中。通过在请求排队结构中组织DRAM命令,DRAM内存控制器可以根据许多不同的因素对DRAM命令进行优先级排序,包括但不限于请求的优先级、给定请求的资源可用性、请求的银行地址、请求的年龄或提出请求的代理的访问历史。
在高性能DRAM内存控制器中,可以促进DRAM命令流水线执行的一种组织方式是按银行排队组织。在按银行排队结构中,假设内存事务请求具有相等的优先级,这些请求根据其各自的银行地址进行排序并定向到不同的队列。图13.7展示了一个按银行排队方式组织的一组请求队列的组织方式。在图13.7所示的组织方式中,内存事务请求被转化为内存地址,并根据它们各自的银行地址定向到不同的请求队列。在一个类似于图13.7所示的组织方式下,如果列访问命令被定向到相同的打开行,则可以从给定请求队列向给定银行发出多个列命令。在给定请求队列已经处理了所有针对相同打开行的待处理请求,并且队列中的所有其他待处理请求都针对不同的行时,该请求队列可以发出一个预充电命令,然后允许下一个银行向内存系统发出命令。
图13.7显示,从按银行排队结构调度请求的一种方法是以循环轮换的方式从一个银行到另一个银行旋转调度优先级。循环轮换的银行旋转命令调度方案可以有效地隐藏给定银行的DRAM银行冲突开销,如果有足够多的待处理请求在调度优先级返回到同一银行之前可以在其他银行中处理。
在close页内存控制器中,循环轮换银行旋转方案最大化了对任何给定银行的请求之间的时间距离,而不需要解决饥饿问题的复杂逻辑电路。然而,循环轮换方案可能并不总是产生最优的调度,特别是对于开放页内存控制器而言。
在open页内存控制器中,地址映射方案将空间相邻的高速缓存行映射到打开的行,而在给定队列中可能存在多个对打开的行的请求。因此,基于权重的优先级调度方案,其中具有最多待处理请求的队列被优先处理于其他待处理请求较少的队列,可能比严格的循环轮换优先级调度方案更为优化。
按银行排队结构可能在大内存系统中受欢迎,其中高请求速率被定向到相对较少的银行。在内存系统中,如果对系统中的大量银行的访问速率相对较低,那么专用的按银行队列在组织请求方面效率较低。在这些内存系统中,队列结构可以更优化地组织为一组通用队列条目,其中每个队列条目可以根据需要定向到不同的银行。
13.4.3 Refresh Management
所有现代DRAM控制器必须处理的一个问题,以确保DRAM设备中存储的数据的完整性,是刷新功能。在现代内存系统短时间不活动的情况下,所有DRAM设备都可以使用DRAM设备控制的self-refresh模式,其中DRAM内存控制器可以在DRAM设备控制自身刷新功能的同时,被临时关闭并置于休眠状态。然而,进入和退出自刷新模式通常在DRAM内存控制器的明确控制下进行,并且在大多数现代DRAM设备中,self-refresh操作在正常操作期间不会被执行。
一个例外是一些伪静态DRAM设备,如MobileRAM,其中温度补偿自刷新被用作正常操作模式的一部分,以最小化刷新功耗。此外,隐藏的自刷新从内存控制器中去除了刷新控制的复杂性,并有助于MobileRAM DRAM设备作为伪静态内存设备的幻觉。在这些设备中,DRAM刷新操作的时序和间隔对内存控制器是隐藏的。因此,在内存控制器发出的内存请求与隐藏的刷新操作发生冲突的情况下,伪静态DRAM设备会发出等待信号,通知内存控制器,来自伪静态DRAM设备的数据返回将延迟到伪静态DRAM设备内部的自刷新操作完成后,并且等待信号被伪静态DRAM设备取消。然而,来自伪静态DRAM设备的等待信号可以延迟内存控制器中的状态转换,有效地引入了内存控制器中的慢信号路径,并有效地限制了内存控制器的操作频率。因此,在正常操作模式下启用隐藏的自刷新功能的显式等待状态信号仅用于相对低频率的、专为电池供电的移动平台设计的伪静态DRAM内存系统中使用,而面向高频率DRAM内存系统的DRAM设备的刷新功能仍由DRAM内存控制器负责。
为了确保DRAM设备中存储的数据的完整性,每个包含有效数据的DRAM行必须每次刷新周期至少刷新一次,刷新周期通常为32或64毫秒。对于一个需要在每个刷新周期执行8192次刷新命令的DRAM设备,数学规定必须每7.8微秒向DRAM设备发出一次全银行并发的刷新命令,以满足64毫秒周期要求的设备。幸运的是,DRAM刷新命令可以在短时间内推迟,以允许延迟关键的内存读取请求继续进行。因此,DRAM控制器不需要严格遵守每7.8微秒向DRAM设备发送一次全银行并发刷新命令的要求。为了利用刷新命令可以在合理的时间窗口内被推迟的事实,图13.8显示了一个队列结构的组织方式,其中微处理器请求流被分成读请求队列和写请求队列,请求命令以恒定的速率(每7.8微秒一个)放入刷新队列。在图13.8所示的结构中,每个刷新请求都附带一个计数,表示该请求已经被推迟的周期数。这样,在刷新请求低于预设的推迟阈值的情况下,所有读取和写入请求都将优先于刷新请求。在系统没有其他待处理的读写请求且处于空闲状态的情况下,刷新请求可以发送到DRAM设备。在系统充满了待处理的读写请求但DRAM刷新请求几乎已经超过了最大推迟时间的情况下,该DRAM刷新请求将获得最高的调度优先级,以确保刷新请求在所需的时间内发生,以确保内存系统中的数据完整性。
考虑中的一个功能,可能会进一步增加未来DRAM内存控制器的复杂性,是每个银行刷新的功能。表13.4说明了tRFC(刷新周期时间)随着高密度DRAM设备的每一代增加,刷新功能的带宽开销也成比例增长。为了最小化DRAM刷新的带宽影响,提出了一个方案,即用单独的刷新命令替代或补充全银行并发刷新命令,每次刷新一个银行中的一个行,而不是同时刷新DRAM设备排中的所有银行中的一个行。
单独的每个银行刷新命令的性能优势可以很容易地计算,因为每个每个银行刷新命令只需要遵守tRC行周期时间限制,而不需要遵守tRFC刷新周期时间限制。然而,每个银行刷新命令提案的一个注意事项是,以每个银行为基础对刷新功能进行精细控制意味着DRAM内存控制器的复杂性必须与发送到每个银行的单独刷新请求成比例地增加,所需的排队结构可能比图13.7中示例的排队结构复杂得多。最后,全银行并发刷新命令还作为DRAM设备可以执行诸如DRAM设备与内存控制器之间的信号重新校准等清理工作的时间段。如果没有全银行并发刷新命令,DRAM设备将失去保证的时间段,其中DRAM设备内部的电路处于活动状态,但DRAM设备与内存控制器的接口处于空闲状态,以执行这些类型的清理工作。
13.4.4 Agent-Centric Request Queuing Organization
在前面的部分中,我们讨论了最大化带宽利用率和降低有效读取延迟的技术。然而,在以前的讨论中没有涉及的一个问题是,无论部署了哪些性能技术,现代DRAM内存控制器设计的一个重要考虑因素是公平性。也就是说,在任何交易请求重新排序机制中,都必须存在反饥饿保障,以确保没有请求可以被推迟无限长的时间。在多个代理共享同一内存系统的情况下,反饥饿保障特别重要。特别是,在具有迥然不同的请求速率和地址序列的多个代理的情况下,必须仔细权衡公平性和性能优化的问题。
例如,
(1)运行典型应用程序的微处理器可能需要相对低的带宽,但来自处理器的读取请求必须被视为延迟关键。
(2)相比之下,连接到相同内存系统的图形处理器可能需要大量的保证带宽,但可以推迟来自图形处理器的单个内存事务请求,以优先处理来自微处理器的请求。
(3)最后,相对低带宽和低优先级的I/O设备的内存事务请求可以推迟,但这些请求不能被无限期地推迟,以免导致I/O设备饥饿。也就是说,在共享共同内存系统的多个代理的背景下,更好的性能可能是指在内存系统的使用上实现公平平衡,而不是获取DRAM设备的绝对最大带宽。
公平性和性能之间的冲突要求是DRAM内存控制器调度机制必须考虑的重要因素。幸运的是,用于处理DRAM设备刷新需求的调度机制可以广泛扩展,以处理需要低延迟或保证带宽的各种代理。也就是说,DRAM刷新命令可以被视为来自需要从DRAM内存系统获得一定数量的保证带宽的代理的请求序列。这个代理以及其他需要不同数量的保证带宽的代理,必须与在带宽方面没有固定要求但必须具有低平均访问延迟的其他代理共享内存系统。
图13.9展示了一个排队结构的组织,其中内存控制器在低延迟代理和保证带宽代理之间进行选择。图13.9显示,来自低带宽和保证带宽代理的请求被定向到一个两级排队结构,其中请求首先被发送到待处理队列,然后在相应的速率控制条件下移到调度队列。速率控制确保非延迟关键的请求代理不能以牺牲其他代理为代价使内存系统饱和。在图13.9中示例的排队结构中,来自低延迟代理的请求通常具有最高的优先级,除非保证带宽代理的调度队列已满。为了确保带宽保证得以满足,在共享的保证带宽代理调度队列已满的情况下,调度优先级必须有利于保证带宽代理。
在前一部分中,我们在获取DRAM内存系统的最高性能的情况下,考虑了以DRAM为中心的请求调度算法,前提是所有请求在重要性上都是平等的,并且可以自由重排序以获得更好的性能。然而,在一个多个代理必须共享内存系统使用的系统中,来自不同代理的并非都具有相同的重要性。因此,为了在整个系统中获得更好的性能,必须考虑以DRAM为中心和以代理为中心的算法。因此,图13.9示出了一个两级调度算法,以确保公平性和系统吞吐量。
13.4.5 Feedback-Directed Scheduling
在现代计算机系统中,内存访问由内存控制器代表处理器或智能I/O设备执行。内存访问请求通常以事务请求的形式进行封装,该请求包含请求的类型、地址和数据(在写请求的情况下)。然而,在大多数系统中,事务请求通常不包含允许内存控制器根据工作负载的特定要求对事务进行优先级排序的信息。相反,内存控制器通常依赖于类型、访问历史、请求代理和内存系统的状态来对内存事务进行优先级排序和调度。在由Hur和Lin [2004]进行的最近的一项研究中,详细研究了使用基于历史的仲裁器来动态选择不同的调度策略。在这项研究中,内存访问请求历史用于动态选择不同的优先级策略,一些基准测试中观察到了5%到60%的加速
Hur和Lin对基于历史的DRAM事务和命令调度算法的探索得以实现,这是因为他们使用了一款集成DRAM控制器的处理器,具体是IBM POWER5。将内存控制器与处理器集成的趋势意味着内存控制器将获得事务调度信息的访问权限,这是作为独立控制器时无法获得的。
随着越来越多的处理器设计集成了DRAM内存控制器,这些处理器可以直接与DRAM内存控制器通信,并根据DRAM内存系统内资源的可用性以及DRAM命令访问历史来安排DRAM命令的执行。特别是,随着多线程和多核处理器与DRAM内存控制器集成,这些DRAM内存控制器不仅需要了解DRAM内存系统内资源的可用性,还需要了解处理器上各个线程上下文的状态和访问历史,以实现最高性能。