再举一个经典的例子,比较基4蝶形算法实现的快速傅立叶变换与基2蝶形算法实现的快速傅立叶变换。二者所需进行的数学运算总次数(加法和乘法次数之和)类似,但其中加法与乘法次数的比值不同。基4的蝶形算法实现中,加法比基2 的算法多,乘法少一些。如果可用的硬件资源更适合进行加法运算,那么基4的算法实现在这样的硬件上运行,性能就会更好。与此类似,FIR(有限冲激响应)滤波算法有时也可以修改以便更好地与硬件资源匹配。例如,若将滤波系数在存储器中重新安排,那么滤波系数和滤波输入就可以使用一个共同的下标变量。有时,硬件直接支持对零值或负值循环计数寄存器进行分支测试,这时,降值循环(count-down loop)就比升值循环(count-up loop)效率更高。
2. 汇编语言编程
在汇编一级进行优化可以最大程度地提高软件效率。在仔细分析算法中最关键的部分和处理器结构的细节之后,汇编语言程序员通常能使编译器产生的代码的性能得到相当大的提高。例如编译器有时并未充分利用处理器的全套指令集,而且几乎从不利用诸如单指令多数据(具备该特性的处理器能够并行执行多个操作)等处理器特性。程序员使用汇编语言就可以全面利用处理器的所有性能。
存储器访问优化
A/V应用中常需处理大量数据,因此片上处理器和片外存储系统就成了这类应用性能的决定性因素。例如,许多价格较低的嵌入式处理器都只有很小的片上1级数据存储器,根本不足以存放音频和视频解压所需的重要数据和系数块。这时,1级数据存储器就成了处理器的性能瓶颈,处理器因此不太可能达到其峰值MIPS应有的性能水平。而在处理一个视频帧时通常又需要访问两到三个相邻帧的数据,这使存储器问题更加严重。此外,视频算法需要大量的代码来实现,所以指令存储器也可能成为性能瓶颈。
表2 根据调用次数进
行编解码器子函数分类。
通过对存储器访问进行优化,可以将存储器访问开销降到最低,从而大大提高整个软件的性能。例如,视频算法在进行处理时默认的处理单元是一帧,也就是说,算法先对一帧视频进行连续操作,直到整个处理序列进行完毕才开始下一帧的处理。而一帧数据通常都远大于处理器的1级存储器容量,因此若需处理一整帧,就必须将一帧分成几部分,每次向存储器中载入一部分,下一次再用新的部分代替旧的一部分数据,如此反覆进行直至整个处理序列全部完成。针对这一情况,可采用以下优化方法:将操作执行的基本单元从一帧改为一帧的一部分,大小刚好能够填满1级存储器。这样,在进行整个处理序列时,这一部分数据就能常驻1级存储器内而无需多次进进出出。这种优化方法减少了对外部存储器的访问,因此能够加快算法的执行时间并且降低功耗。
软件测试
对消费性媒体产品进行测试所需的的数据量太大,音、视频信号质量的评价中有很多主观因素,而且音、视频编解码器所支持的工作模式也很多,因此要进行彻底的测试十分困难。其中最难的就是测试所有硬、软件子系统的互操作性,以及这种互操作性对产品实时性能的影响。如果处理器本身能力有限,而软件优化程度又太高,就会使产品处于一个不稳定的平衡状态,从而影响其实时性能。也就是说,对编解码器进行仔细优化之后可以将系统性能提升到具备实时操作能力的等级,但这时哪怕是轻微的干扰都可能造成系统故障。因此,彻底的测试就显得尤其重要。
数据I/O要求较高
音、视频设备的数据吞吐量很大,因而对这类设备进行测试时,首先就要求测试设备能够接收很大的输入测试向量并能捕捉相应的输出数据流。终端用户访问的通常是数模转换之后的模拟输出数据流,而开发人员却需要捕捉数字模式下的输出数据才能进行测试。如何在硬件原型可用之前测试压缩算法的实现性能,这是一个十分重要的问题。由于测试中数据量太大,如果利用处理器的仿真模型进行测试,速度太慢,因此需要真正的硬件。用开发板测试音、视频软件时,必须确保大量经过压缩的数据和解压后的数字音、视频数据能够进出处理器。而对开发人员而言,这就意味着,如果能够选用具备足够I/O能力的开发平台进行测试,就会节约很多测试时间,并且在测试开始后减少很多麻烦。
音、视频信号品质
表1中给出的音、视频压缩算法都是“有损”的或者说“感性”的算法,这些算法利用人类视觉和听觉上的弱点来降低算法对存储和带宽的要求。这就造成了压缩和解压之后重建的输出并非对原始信号的准确还原。有损压缩技术使测试变得复杂,因为这时若继续采用诸如重建输出与原始输入的信噪比之类传统测试方法采用的指标来衡量,就会得到信号严重恶化的测试结果,但观众和听众却往往不会感到这种变化。有损压缩算法中利用了当前信号的上下文信息,而测量信噪比这样的传统测试方法没有提供这样的信息,因此对有损压缩算法必须采用其他测试方法。
在开发一个压缩算法时,结构化的视听测试能够为开发人员提供一些反馈信息,让他们知道算法能达到怎样的视、听觉品质。压缩算法完成之后,开发人员就要决定怎样测试这一算法的多种实现方式。实现方式测试通常依赖于一组特殊的测试向量和一个官方版本的“参考”编解码器来进行。这些测试向量和参考编解码器则往往由压缩算法的提供商或者由一个标准化组织给出。被测的算法代码实现与参考编解码器之间可容忍的误差随编解码器的不同而有所不同,但这一误差通常都很小,甚至为零。
必须注意的是,参考音频编解码器通常采用浮点算法,而考虑到成本因素,实际用于实现这些编解码器的嵌入式媒体设备往往采用定点算法。理想情况下,定点编解码器的输出和浮点参考编解码器的输出是匹配的,但实际上二者的匹配程度取决于算法定点实现的数字精度。若定点实现的编解码器质量较差,那么在音频内容较好时这样的编解码器还可以正常工作,一旦音频内容不是很好,它就会出故障。厂家提供的测试向量是针对浮点算法开发的,无法充分测试定点实现的缺陷。因此,要保证彻底测试一个定点实现,就必须获得或者创建一些测试向量,这些测试向量能够全面测试算法的整个潜在动态范围。
实时性能:消费性媒体设备必须具备的性能
很明显,消费性媒体设备需要具备实时性能,否则音频信号会变得结结巴巴,视频信号会出现停顿和跳跃。要想将系统在实时工作时的表现推到极限,开发人员通常需要对资源消耗最大的工作模式进行测试,例如比特率最高的模式、采样率最高的模式、视频分辨率最高的模式以及音频通道最多的模式。这是一个很不错的出发点,但并不能保证通过这种方法一定能够测试到最糟糕的情况。因为压缩算法常有一些由数据决定的执行通路,这时,处理器运行软件的通路在很大程度上由输入数据的特性决定。还有更复杂的情况,在某些处理器中,乘法等基本操作的循环执行次数也取决于输入数据。因此,要想成功地测试出系统在最坏情况下的实时性能,不但要在资源消耗最大的工作模式下测试,还应具备能够确保处理器选择最坏执行路径的输入数据流,而且对所有数据依赖定时的操作都灌以最坏情况的输入。
作者:Jeff Bie