在上一期中,我们讨论了分别基于寄存器和描述符的DMA模式。在本文中,我们将在系统层面上探讨应用中关于数据移动的各种选项所应做出的某些重要的决策问题,以及某些先进的DMA功能特性如何协助数据在多媒体系统中有效地移动。首先让我们重新回顾一下DMA模式,以便以之说明另外一两条关于何时选择其中一种模式而非另一种模式的指导原则。
对于规模相同、连续、单向的数据传输来说,自动缓冲方案是最合理的。DMA配置寄存器只要设置一次,就可以自动地在传输结束的时候重新载入。如果采用多维寻址,则可以设置多重缓冲,在每次缓冲结束时可以单独设置各次中断的触发。
到一个音频编码解码器的传输就是这种类型事务。你所选取的子缓冲区的数量应该与你需要执行的处理的类型相一致。对于连续传输来说,只要确保能让每个缓冲器的最大处理间隔小于取空一个缓冲器所花费的时间即可。
如果在给定通道上的传输在方向和尺寸上都将是可变的,描述符模式就是最佳的选择。试考虑在内部和外部的存储间发生的一系列小规模的传输,如果数据块的尺寸发生改变,或者如果你希望以一种非连续的方式来在缓冲器中处理数据,则可以为此建立描述符。
高速缓存 vs DMA
我们接下来将考察系统数据转移的某些情形,在这些情形中,我们需要在高速缓存和DMA之间做出选择。为此,我们首先需要考察一项在应用内部存在的各种数据移动类型。
通过片上外设来将数据转移到系统内或者将其移到系统外是一种最容易说明问题的情况,因此我们以这些数据的转移为起点开始讨论。许多外设可以在使用内核存取还是用DMA通道来转移数据之间做出选择。一般来说,如果可以做出选择的话,你应该使用DMA通道。DMA控制器之所以成为最佳选择,是因为数据往往要么来得太慢,要么来得太快,处理器无法高效地对其进行实时处理。
当我们采用慢速的串行器件(如SPI端口或者UART)时,数据的传输速率远低于处理器内核运行的速度。内核对这些类型的外设的访问必然涉及对一个映射存储器的寄存器的某些位的轮询(polling)。即使当外设的工作速度与处理器时钟相比较很低的话(这意味着访问的频率将会降低),轮询也是一种浪费。在某些情况下,外设有能力发出中断,指示内核传输已经发生。不过,在这里,每次增量数据传输完成后都会遇到为中断提供服务的开销问题,包括前后条件(context)切换的时间。
另一方面,使用DMA控制器来执行传输,使得系统可以精密地控制在发出中断前所完成的传输的次数。而且,这种中断可以在每个数据“块”的末尾发生,而不仅仅是在每个字节或者字之后。
在吞吐率分布的另一端,更为高速(例如以10~100MHz)的并行外设可能无法选择内核传输的方式。原因为:首先,以这种方式进行设定时,处理器会频繁地访问外设;其次,与高速外设相关的处理几乎总是对数据块进行的。无论是在一个信号处理应用中通过FFT完成,还是在图像处理系统中进行二维卷积(convolution),处理器在送往缓冲器的最后一个数据采样一到达时就开始其操作。这里,用于指示一个数据块传输结束的中断可以出现在数百次甚至上千次传输中。
无论外设进行何种类型的传输,DMA通道都应该带有多个缓冲器,以便让处理器能在数据填充入下一个缓冲器时访问当前的缓冲器。如果系统更为复杂,则有可能需要实现多个同步进行的数据块传输。例如,除了可以访问当前的数据块并采集下一个数据块,还可能有必要将最后一个处理过的数据块发出,以备未来之需。类似的,要处理当前的帧的话,也有可能需要参考数据块。各种各样不同类型的应用都确实存在这一情形,包括大多数类型的视频压缩应用。(关于高速缓存与DMA之间的选择指南内容,祥见《电子工程专辑》网站)
DMA控制器特性
为了在多媒体系统中有效地运用DMA,就必须有足够多的DMA通道,有一对以上的存储器DMA(MemDMA)流充分地支持处理器的外设集。这是一个重要的问题,因为必然存在如下的情况:在未经处理的媒体流进入外部存储器(通过高速外设)的同时,数据块在外部存储器和L1存储器之间来回传输,以供内核处理。而且,DMA引擎允许在外设和外部存储器间进行直接数据传输,而不要求数据在L1存储器中“暂驻”,这可以在那些数值计算密集的算法执行中避免额外的数据传递。
程序开发者常犯的一个错误会使得开发过程中的调试问题变得复杂化。外设及其相应的DMA通道往往会提供一个可选的错误中断,在开发中该中断应该始终处于使能状态,这样可以节省数小时的调试时间。错误中断一般是用于指示编制的程序中出现了某些错误(容易解决),或者外设下溢/溢出(情况更为复杂)。很多情况下,当编程者在项目开始的时候用数据流来建立框架(framework)时,这些类型的问题只会在后来运行中,当应用处理器件被加上的时候才出现。
其他重要的DMA特性包括对DMA通道设定优先级,以满足当前外设任务要求,以及对相应的DMA中断进行配置以便与这些优先级水平相匹配的能力。这些功能有助于确保数据的缓冲区不会由于DMA活跃在其他的外设上而出现溢出,它们为程序开发者提供了额外的自由度,能根据每个DMA通道的数据往来情况对整个系统进行优化。
系统性能的修调
随着数据率和性能要求的提高,设计者能否具有对“系统性能修调”等控制选项进行操作的权限,也将变得十分关键。例如,DMA控制可以针对在每个时钟周期上传送一个数据字这一需求进行优化。当同一方向上有多个传输在进行时(例如,都从存储器出发,发往外部存储),这往往就是对控制器进行操控的最有效率的方法,因为它可以防止DMA总线出现闲置。
但是,在需要进行多路双向视频和音频流传输的情况下,“方向控制”就成为必不可少的措施,其目的是防止一条数据流完全占用整条总线。例如,如果DMA控制器始终将DMA总线的使用权交给任何一个准备好传输一个数据字的外设,则使用外部DRAM时总的吞吐率将出现下降。在数据传输几乎每个周期都变换方向的情况下,与外部存储总线花费的转向时间相应的延迟将会显著地降低吞吐率。
于是,可以让通道来编程设定突发量大小(burst size)的DMA控制器将具有超出那些传输大小固定的控制器的性能。因为每个DMA通道可以将外设与内部或者外部存储相连接,所以为可能会发出紧急占用总线请求的外设自动服务的能力也是非常重要的。
对于多媒体应用来说,片上的存储器几乎总是不足以存下整个视频帧数据。因此系统往往必须依靠L3 DRAM来支持相对较快的、对大缓冲区的访问。处理器与片外存储器的接口在涉及高效的媒体框架方面是一个主要的因素,因为对外部存储的存取模式必须经过深思熟虑,以便能保证最佳的数据吞吐能力。
使用DMA和/或高速缓存总是有助于提高存储的性能,因为它们实现了大数据块在同一方向上的传输。DMA传输一般是将大的数据缓冲区从一个位置转移到另一个位置,而高速缓存线填充(cache-line fill)则是将一组在位置上连续的存储器中的数据移入或者移出设备,利用同方向的块传输来实现。
除了使用DMA或高速缓存,还有若干高层次上执行的步骤,它们可以确保数据流能流畅通过任何系统中的存储器。两个关键步骤分别是类似的传输编组以及优先级分配和裁决方案的使用(详见《电子工程专辑》网站)。
在多媒体系统应用的考虑
1. 使用DMA控制器来剔除数据
DMA控制器可以用于“过滤”从摄像机流入一个系统的数据量。让我们考虑一个视频流正被送入存储器进行某种形式的处理的情形,当数据并不需要被再次送出来进行显示的话,就不必将逆程消隐(blanking)数据送入存储器缓冲区。
处理器的视频端口常常直接连接到一个视频解码器或者一个CMOS传感器上,并连续地接收采样。也就是说,外部的器件不断送入数据和空白显示信息。DMA控制器可以被设定为仅仅把有效的视频送入存储器中,使用这样的功能就可以同时节约存储器空间和总线带宽。
对于NTSC视频流而言,这种消隐显示信息占到了总输入视频带宽的20%以上。存储器节省带来的好处并不大,因为额外的存储空间可以以外部SDRAM的形式来提供,而所带来的系统成本变化很小。更重要的是,在总的处理周期中所节约下来的带宽,通常用来输入消隐显示信息的时间,都可以重新分配给系统中的某些其他的任务。例如,这些带宽或时间可以用来发送压缩的数据或者输入来自于过去的帧的基准数据。
2. 双重缓冲
通常,在源视频和最终显示的内容之间存在数据率差异的系统中,有必要在原有的内容和新的视频帧之间实现平滑的切换,这可以通过使用双重缓冲设置来实现。一重缓冲指向目前的视频帧,该帧以一定的刷新速率发送到显示器;第二重缓冲则填入最新输出的帧。当后一重缓冲区被填满时,DMA则发出中断信号,表明该将新的帧输出到显示器了。此时,第一重缓冲开始用处理过的、待显示的视频帧进行填充,而第二重缓冲则输出目前显示的帧。双重缓冲以类似于“打乒乓球”的方式来回切换。
应该注意的是,除了双重缓冲外,也可以使用多重缓冲,以便为同步化提供更多的余量,以及降低中断的频率和相应的延迟。
3. 2D DMA的考虑
数据通过数字链路(如I2S)传输时,它可能包含几个通道。例如,这些通道必须复用在一个数据线内,通过同一个串行端口传输。此时,2D DMA可以用对复用的数据进行去交织(interleaving)处理,以便让每个通道在存储器上直线排列。图1给出了图形化的描述,在图中,来自于左右通道的采样被解复用,变为两个单独的数据块。这种自动化的数据分配结构对于那些采用了数据块处理的系统来说具有极高的价值。
图1:N个采样的数据块分离为L(左)和R(右)通道
对于视频传输来说,2D DMA提供了若干系统层面的好处。对于刚开始着手的开发者来说,二维 DMA可以方便宏模块与外部存储间的往来传输,让数据的处理成为实际的传输操作的一部分,这消除了传送非连续数据传统上所需的额外开销。它还可以让系统通过有选择的传输(例如,仅传输一幅输入图像中所需区域,而不是整幅图像)来最大限度地减小数据的带宽。
另外一个例子是,2D DMA 可以让数据以一种对处理来说更为自然的顺序放置在存储器中。比如,正如图2所示的那样,RGB数据可以从一个CCD传感器出发,以交织的RGB888格式进入处理器的L2存储器,如果采用2D DMA,它可以按照红、绿、蓝平面分别送入L3存储器。视频和图像数据色彩空间分量的交织/去交织可以省下在处理前进一步移动数据的麻烦。
图2 通过2D DMA来分离间插在一起的数据。
4. 同步的音频和视频流
在一个多媒体系统中,流内容往往同时包含音频和视频分量。因为这些流运行的数据率的缘故,必须用DMA通道来与音频编码/解码器和视频编码器进行接口。重要的是,需要确保流是同步的,因为这种协同性是观看质量的一个主要影响因素。
维持同步有多种方法,最常用的技术是为每组音频和视频缓冲区建立起一组DMA描述符表,并让处理器管理这些表。
因为音频流中的数据丢失比视频帧的丢失更容易引起人们的注意,音频缓冲往往被设定为“主”流。即,需要让音频缓冲区以连续的模式进行循环运转更为重要。通过保证音频流的连续性,处理器可以对视频帧显示进行任何必需的调整。从DMA缓冲区的角度来看,针对每个音频和视频缓冲器分别生成一组描述符。每个描述符表设置为可以用一对指针来控制,一个指针用于填充缓冲区,而另一个则用于清空缓冲区。
每个描述符表都需要更新维护,以便确保读和写指针不会相互“交叉”,即处理器不应该对正在发送数据的缓冲器进行刷新。类似的,DMA的控制器不应该对处理器正在对其填充数据的缓冲区进行数据填充操作。
为了实现音频和视频的同步,必须保持一个总的时间基准。每一个解码后的数据缓冲区都可以在存储器中利用对应的时间标签(time tag)来设立。如果音频流是“主”流,写入缓冲就是完全循环性的。如果视频帧不得不丢弃,负责缓冲器清空的DMA指针可以被重新编程设定为与最接近当前的音频缓冲数据的时戳(time stamp)的时间相一致。
5. 利用DMA控制器降低功率
在一个具有电源管理功能设计的处理器上,DMA控制器可以为系统的总体功耗降低提供一种有价值的工具。让我们考察一下这是如何实现的。
当处理器并不对缓冲区进行积极的操控时,它可以设定为处于空闲状态。处于这种无活动的状态中时,时钟可以被关闭,有时甚至电压也会被降低—这两种措施都将减少处理器的功耗。
试考虑一种音频解码系统。其处理器对编码后的内容进行解码操作。解码后的缓冲数据在存储器中累积起来,一旦缓冲区碰上“高水位”(high-water)标记时,处理器就被置于休眠模式,同时,DMA控制器则从缓冲器中采集数据,馈送给音频编码/解码器。为了保证良好的音频品质,这种传输必须连续进行。
若要实现“低水位”标记,则可以通过将DMA控制器编程为在传输了一定量的数据采样后发出一个中断信号。中断则可以被编程设定为唤醒事件,从而让处理器脱离其休眠模式。处理器可以重新填满缓冲区,于是,当DMA控制回转到缓冲区的起始点时,就可以提供新的数据。
如果这一例程可以连续运行,则净效果是处理器的占空比(即处理器有效工作的时间)大大降低。
本文小结:
一个复杂的系统可能会涉及大量并行运行的DMA通道。当DMA通道用描述符进行编程设定时,描述符的数量会出现爆炸性增长。在这些情况下,最好是实现某种形式的DMA队列管理器。DMA管理器在用来管理并行的传输的调度时也有很好的效果。
总之,一个DMA控制器是任何多媒体系统的一个有机的组成部分。理解其复杂性,以便充分地对一项应用进行优化,将具有十分重要的意义。然而,它绝不是系统中唯一的运行操控部件,人们也必须处理好其他的系统资源,如存储器和处理器内核与DMA控制器间的关系,要在它们之间实现完美的平衡,就必须理解数据在系统中的转移的基本过程和原理。