DRAM控制器藏在您的系统核心芯片系统(SoC)中——可能有两个,甚至是四个。有一些精心制作的逻辑小模块,用于连接SoC内部和外部DRAM,它们并没有引起系统设计人员的注意。它们有可能造成很大的问题,浪费带宽,占用太多的能耗,甚至导致数据被破坏。
DRAM控制器能否正常工作会使得系统有很大的不同,有的系统能够满足其设计要求,而有的系统则运行缓慢,过热,甚至失败。不论哪种情况,最终是由系统设计团队承担责任,他们一般很少掌握控制器的信息。
成功还是失败都源自我们要求DRAM控制器所做的工作。模块不仅仅是一个接口。在高级系统设计中,DRAM控制器必须很好的处理SoC体系结构复杂而又难以预测的存储器申请,以及一侧的系统软件申请,还有另一侧DRAM芯片设计复杂的时序和约束要求。能否处理好这些关系会在多个方面影响DRAM吞吐量:这很容易在系统性能上体现出来。
为解释这些问题——以及系统设计人员能够对此做什么,我们需要回答三个主要问题。首先,我们应检查DRAM芯片提出的要求。然后,需要讨论SoC体系结构对存储器访问模式的影响,第三,研究一个高级DRAM控制器的结构和功能。通过这三部分,我们得出系统设计的一些结论。
DRAM需要什么
系统规划对外部存储器的要求是确定性随机访问:任何时候来自任何位置的任意字,具有固定延时。但是,确定性随机访问恰恰是现代DDR3 DRAM所不能提供的。
相反,DRAM提供任何您需要的字,但是具有复杂的时序约束,因此,很难知道数据究竟什么时候出现。 图1 中“简化的”状态转换图简单解释了为什么会这么复杂。这种复杂度也意味着,命令到达DRAM芯片的顺序会对时序以及带宽有很大的影响。要理解这一点,我们需要深入了解DDR3 DRAM。
图1.DDR DRAM芯片“简化的”状态图显示了控制器设计人员所面临的复杂问题。 (图片) DRAM芯片将数据存储在电容阵列中。当您读写数据时,您并不会直接访问阵列。而是在读写之前,您激活阵列中的某一行。激活命令使得DRAM读取该行中的所有列的所有比特,将其送入传感放大器块,它实际上用作该行的本地寄存器文件。然后,您可以对传感放大器上的数据发出读写命令。通过这种方式,能够非常快的读写已经激活的行:一般是三到五个时钟来开始一次突发传送,然后,在突发期间传送每个字节需要一个时钟。例如,这种时序安排使得DDR3 DRAM非常适合L2高速缓存数据交换。
但是,如果您不使用已经激活的行,那么会非常复杂。改变行时,即使是一个字节,您也必须对当前行去激活,然后激活一个新行。这一过程需要确定已经在一段时间内激活了当前行。由于读取DRAM单元是破坏性的,因此需要最小延时:您激活了一行后,DRAM实际上是将最新到达传感放大器上的数据复制回比特单元阵列中,然后刷新行。您可以在此期间读写当前行,但是,要确定在您改变行之前完成了这一过程。
即使满足了这一要求,也还有其他问题。您必须对阵列预充电。预充电命令使得传感放大器中的数据无效,提升阵列和传感放大器输入之间导线上的电压,使得电压值位于逻辑0和逻辑1电平之间。这种准备是必要的,比特单元电容上很小的电荷都会传送到导线上,以某种方式提示传感放大器。
对导线进行预充电之后,您必须向新行发送一个激活命令,等待操作完成,然后,您最终可以发送一个读操作新命令。加上所有涉及到的延时后,即,读取字节序列的最差情况,每一字节都来自不同的行,这要比读取来自一个新行连续位置相同数量字节的时间慢十倍。
这种不同还只是部分问题。如图2 所示,DDR DRAM有多个块:与比特单元无关的阵列。DDR3 DRAM中有八个块,每一块都有自己排列成行的传感放大器。因此,原理上,您可以通过激活每一个块中的一行,读写较长的突发,然后,对每一激活后的行进行读写操作——实际上是对块进行间插操作。唯一增加的延时是连接每一块的传感放大器和芯片内部总线的缓冲的切换时间。这一延时要比对相同块中一个新行进行预充电和激活的时间短得多。
图2.一个典型的DDR DRAM结构图。一个DDR3器件会有8个块,而不是4个。(图片) 这就是原理。实际中,您可以对块进行间插处理,但是有一个限制,不是基于DRAM逻辑,而是芯片能够承受的热量。这种限制可以通过著名的“滚动四块访问窗口”,即,tRAW来表达:您一次能够有四个激活块的最长时间。这一规则实际上有例外,只要您从一个块转向下一块之前,在一个块上保持一定的时间,那么,您可以有连续激活的8个块。但是您应该知道:这比较复杂。
建立一个控制器
与前面所述不同的是DRAM时序非常复杂,接近混沌。从DRAM芯片设计人员的角度看,这非常合理,但是,很难满足多核SoC的需求。DRAM序列或者时序命令上看起来无关紧要的小改动会导致您访问存储器的带宽的巨大变化。由于存储器带宽通常是关键任务的瓶颈所在,因此,带宽的变化很快就会影响系统性能。然而,命令序列和时序来自应用程序和系统软件之间,以及系统硬件各种单元之间复杂的交互——包括缓存控制器、存储器管理器、直接存储器访问(DMA)控制器和加速器,以及DRAM控制器。
SoC的功能越来越强大,这种情况会更加复杂。目前,一个多核系统级IC会有同时运行的两个甚至更多的多线程CPU,导致共享L2高速缓存来读取指令线,随机对数据线进行读写操作。同时,计算加速器以自己的方式遍历数据结构。一个器件可以处理流视频,另一个用于矩阵乘法预读取,第三个执行路由表的随机访问。增加一个散射收集DMA控制器,处理光纤接口、硬盘和显示器之间的数据,结果是,在DRAM控制器的系统侧会有些不协调。
如果DRAM控制器只是按照系统接收顺序进行操作,那么,优化DRAM操作的工作会同等落在规划人员、设计人员和软件开发人员上——这是很难做到的。Altera公司战略市场经理Argy Krikelis提醒说:“特别是多核设计,规划人员遇到定位和性能问题。”责任落在DRAM控制器上,那么,尽可能利用其信息消除这种不协调,转换为经过优化的命令流。
深入了解DRAM控制器就会知道,这些模块的设计人员怎样处理这些难题。您可以认为一个现代DRAM控制器有三个主要模块——物理接口、命令处理器以及事物处理器——如图3 所示。
图3.一个现代DRAM控制器涉及到事物处理器、命令处理器和物理接口。
(图片) 物理接口连接DRAM芯片或者存储器模块。它读取来自命令处理器的一个命令流,将具有正确时序的命令发送至DRAM芯片,管理相关的数据字节流。接口收发器、命令和数据同步缓冲,以及产生正确命令和数据时序的状态机都含在这一模块中。而且,还有用于进行复杂的初始化操作的状态机,校准DDR3 DRAM规范设定的序列,如图1所示。此外,某些应用的物理接口还会包括自测试、诊断和误码探测以及纠错硬件。当您改变DRAM的容量或者速率等级时,必须调整物理接口。
物理接口的上游是命令处理器。这一模块跟踪DRAM的状态,将到达总线读写周期转换为相应的DRAM命令序列。例如,命令处理器会找到通过其输入队列散射连续字的总线读序列,然后,向其输出队列发出预充电,激活,以及模块读命令。对此,命令处理器必须知道当发出新命令后,将打开哪一芯片的哪一块的哪一行。在某些设计中,命令处理器还处理地址重新映射,在多个块上扩展一个连续的数据结构。
随着对带宽需求的增长,命令处理器的复杂度也在不断提高。例如,处理器会提前处理其输入队列,重新安排操作,尽可能保持在激活的行上,重叠预充电读操作,或者对块进行间插操作。最重要的是,处理器会尽量避免一个块的行之间出现乒乓效应。必须确定所有这些调整,并且随时能够进行调整。
这方面的努力会有其回报。Krikelis说:“我们看到在某些应用中,分组和重新排序能够实现92%的理论最大DRAM带宽。”
最后,事物处理器位于命令处理器和SoC的其他部分之间。一般有一些通道连接至SoC的高速中心交换结构上。事物处理器的主要工作是将到达的各种通道的读写数据流进行组合,加上优先级,这样,每一通道得到了所需的延时和带宽——因此,每一高速缓存控制器、DMA引擎或者这些通道另一端的加速器也得到了所需的延时和带宽。
在动态环境中选择这种优先级方案并不容易。如果您不能精确的预测每一通道的数据流特性,那么,这会非常困难。理想情况下,工作负荷是固定的,因此,您可以为其优化优先级方案。或者,会有一些清晰的访问模式,随着数据流的变化而提供动态调整优先级。Krikelis说,系统规划人员和控制器设计人员研究了这一问题,使用了从表格到商用DRAM仿真工具的所有工具。但,还是无法让工作更简单一些。
在某些情况下,应用的特征很明显,事物处理器会承担更多的工作。Krikelis说,可以对最近的DRAM行进行高速缓存操作,或者控制器中经常被激活的行进行高速缓存操作。而且,在某些情况下,设计人员可以针对某些通道进行一些特定任务的重新排序或者某些读写操作。
高级DRAM控制器中的三个主要模块协同工作,能够使复杂多核SoC尽可能接近最大理论DRAM带宽。但是提高带宽可能需要牺牲延时,最高优先级线程除外。某些控制器设计会有32或者64深命令序列,意味着,低优先级访问会长时间停留在序列中。一般而言,DRAM控制器能够进行的工作越多,它处理的SoC体系结构和组合任务就越具体。这就把难题留给了系统设计人员。
回到系统级
您可能会说:“很有趣。对此,我应该做什么?”正如我们在开始所阐述的,软件、系统硬件以及控制器之间的交互会决定您从DRAM那里能够得到的实际带宽。作为一名系统设计人员,您的确有一定的自由度。
最好的方法一般是采用SoC供应商的参考设计。参考设计团队完成了他们的工作。理想情况下,您完全按照设计人员所希望的方式来使用SoC。Krikelis提醒说:“如果您购买了ASSP,那就没有太多的选择。DRAM控制器和芯片中的其他模块会针对特定的应用进行整体优化。”
参考设计中的这些软件也是在知道了这些优化后才编写的。例如,经验丰富的编程人员会尽可能保持存储器参考位于行中,可以同时打开,以便减少高速缓存未命中和DRAM行未命中等问题。他们能够熟练的在块上分配数据结构,采用间插操作。他们可以安排CPU内核、加速器和DMA的工作,避免控制器可能解决不了的冲突问题。他们知道,对于控制器中未处理器的命令,DRAM、高速缓存以及命令队列中的数据,数据一致性是他们要解决的关键问题。采用这类参考设计的系统设计人员的工作是尽量不打破这种一致性。
但是有些时候,系统设计人员会有更大的自由度。Krikelis指出,如果DRAM物理接口是可配置的,您可以通过简单的使用更大的DRAM来提高存储器的有效带宽。在某些情况下,可以调整一些DRAM控制器的内部参数,例如,分配给通道的优先级、重新排序算法,以及命令队列的深度等。
但是,在某些情况下,仅仅进行调整是不够的。Krikelis提醒说:“没有一个简单的答案来满足所有人的规划需求。有时候您需要建立自己的访问抽象层。”
对于资金雄厚的有影响的设计团队,这意味着,与ASSP供应商合作,修改事物处理器,甚至是命令处理器。对于其他规模较大的工程,DRAM带宽需求会满足开发ASIC的要求。对于不能满足ASIC前端成本的设计,替代方案是系统级FPGA。通过这些方法,系统设计人员在控制器的某些部分采用现有的知识产权(IP),设计尽可能多的定制操作和命令处理操作,以满足其需求。
即使系统团队选择不去修改DRAM控制器,他们理解其功能也很重要。很多选择都能够实现与DRAM控制器的互操作,从DRAM芯片选择到数据怎样在系统中输入输出,线程怎样分配给处理器,应用程序怎样将数据结构映射到物理存储器中等。难点是怎样高效的使用DARM带宽,最终目的是提高整个系统的性能和能效。
10/23/2012
|