随着“开源”C / C ++算法成为嵌入式处理应用程序中基于版税的代码越来越受欢迎的替代方案,它们带来了新的技术挑战。其中最重要的是如何优化所获取的代码以在所选处理器上良好地工作。这个问题是至关重要的,因为为给定处理器系列编写的编译器将利用该处理器的优势,可能会牺牲其他领域的低效率。当在不同平台上直接运行相同的算法时,性能可能会降低。本文将探讨将此类开源算法移植到ADI公司的Blackfin ®处理器,并在此过程中概述导致代码优化的“攻击计划”。
什么是开源?
通常理解的“开源”定义是指任何带有源代码的项目,可供其他程序员使用。开源软件通常在软件程序员社区内协作开发并自由分发。例如,Linux操作系统就是以这种方式开发的。如果一切顺利,最终的努力提供了一个不断发展,强大的应用程序,经过充分测试,因为许多不同的应用程序利用了代码。鼓励程序员使用代码,因为他们不必为此付费或自行开发,从而加快了他们的项目进度。他们成功使用该代码提供了进一步的测试信息。
“开源”的认证标志由开源倡议(OSI)所有。如果分发条款符合OSI的开源定义,那么开发为可自由共享和发展的代码可以使用开源商标。这要求根据某些指导原则将软件重新分发给其他人。例如,在通用公共许可证(GPL)下,必须提供源代码,以便其他开发人员能够改进或发展它。
什么是Ogg?
整个开发人员社区都致力于为数字媒体创建开放标准和应用程序。其中一个组织是Xiph.Org Foundation,一家非营利性公司,其目的是支持和开发免费,开放的协议和软件,以服务于公共,开发和商业市场。这个伞式组织(见图1)负责监督视频 - (Theora),音乐等技术的管理 - (有损Vorbis和无损Flac),以及语音(Speex)编解码器。
术语Ogg表示保存多媒体数据的容器格式。它通常用作生成数据的特定编解码器的前缀。我们将在这里讨论的音频编解码器Vorbis使用Ogg将其比特流存储为文件,因此它通常被称为“Ogg Vorbis”。事实上,一些便携式媒体播放器被宣传为支持OGG文件,其中“Vorbis”部分是隐含的。下面讨论的语音编解码器Speex也使用Ogg格式将其比特流存储为计算机上的文件。但是,互联网协议语音(VoIP)和其他实时通信系统不需要文件存储功能,并且使用像实时传输协议(RTP)这样的网络层来封装这些流。因此,即使Vorbis通过多播分发服务器通过网络传输也会丢失其Ogg shell。
什么是Vorbis?
Vorbis 是一种完全开放,无专利,免版税的音频压缩格式。在许多方面,它在功能上与普遍存在的MPEG-1/2第3层(MP3)格式和较新的MPEG-4(AAC)格式非常相似。该编解码器设计用于16至128 kbps /通道的可变比特率的中高质量(8 kHz至48 kHz带宽,> 16位,复音)音频,因此它是音乐的理想格式。
最初的Vorbis实现是使用浮点运算开发的,主要是因为编程容易导致更快的发布。由于大多数电池供电的嵌入式系统(如便携式MP3播放器)使用成本更低,电池效率更高的定点处理器,开源开发人员社区创建了Vorbis解码器的定点实现。被称为 Tremor 的定点Vorbis解码器的源代码是根据许可证发布的,允许将其合并到开源和商业系统中。
在选择特定的用于移植Vorbis解码器的定点架构,分析从压缩比特流中恢复音频所涉及的处理类型非常重要。 Vorbis解码过程(和其他类似算法)的通用处理器流程如图2所示。与许多其他解码算法一样,有两个主要阶段:前端和后端。
< p>在前端阶段,主要活动是标头和数据包解包,表查找和霍夫曼解码。这种操作涉及大量条件代码和相对大量的程序空间,因此嵌入式开发人员通常使用微控制器作为前端。
后端处理由过滤函数,逆变换和一般向量运算定义。与前端阶段相比,后端阶段涉及更多的循环结构和内存访问,通常使用较少量的代码。由于这些原因,嵌入式系统中的后端处理历来由成熟的DSP主导。
Blackfin处理器架构统一了微控制器(MCU)和DSP功能,因此不再需要两个单独的设备。它可以有效地用于在单个芯片上实现前端和后端处理。
什么是Speex?
Speex 是开放式的-source,专利用于语音的专利音频压缩格式。虽然Vorbis用于压缩所有类型的音乐和音频,但Speex仅针对语音。出于这个原因,Speex在相同质量水平的语音上可以取得比Vorbis更好的结果。
正如Vorbis与基于版税的算法(如MP3和AAC)竞争一样,Speex在语音编解码器市场中与GSM-EFR和G.72x算法共享空间,例如G.729和G.722。 Speex还具有许多其他编解码器中不存在的功能。这些包括可变比特率(VBR),在同一比特流(8 kHz,16 kHz和32 kHz)中集成多个采样率,以及立体声编码支持。此外,Speex的最初设计目标是促进融入互联网应用程序,因此它是VoIP电话系统的一个非常强大的组件。
除了其独特的技术特性,Speex还具有成本的主要优势“没有“ - 可以分发和修改以符合特定的应用程序。源代码以类似于Vorbis的许可证分发。由于项目的维护者意识到将Speex嵌入到小型定点处理器中的重要性,因此在主代码分支中引入了定点实现。
在Blackfin处理器上优化Vorbis和Speex
当现有应用程序(如Vorbis或Speex)移植到新处理器时,立即“开箱即用”代码性能是最重要的考虑因素。但是,软件工程师可以通过熟悉可用于优化整体性能的众多技术来获得巨大回报。有些只需要很少的额外努力。
将任何软件移植到Blackfin等嵌入式处理器的第一步是定制低级I / O例程以满足系统需求。例如,Vorbis和Speex的参考代码假定数据源自文件和处理后的输出存储到文件中(主要是因为这两种实现最初都是在Unix / Linux系统上运行的,其中文件是I / O例程可用)。然而,在嵌入式媒体系统中,输入和/或输出通常连接到在数字和现实模拟域之间转换的A / D和D / A 数据转换器。图3显示了可能基于Vorbis的媒体播放器实现的概念性概述。输入比特流从闪存传输,解码器输出驱动音频DAC。此外,虽然一些媒体应用程序(例如,便携式音乐播放器)仍然使用文件来存储数据,但许多系统用网络连接替换存储。
当优化像Vorbis解码器这样的系统时有效地运行,有一个有组织的攻击计划是一个好主意。一种可能性是首先从C内优化算法,然后简化系统数据流,最后在装配级别调整代码的各个部分。图4通过连续的优化步骤说明了处理器负载的代表性减少,并显示了该方法的效率。
编译器优化
可能是最有用的代码优化工具是一个很好的探测器。使用VisualDSP ++ for Blackfin中的统计 profiler ,程序员可以快速关注在处理器执行代码时变得明显的热点。在许多实现中,20%的代码占用了80%的处理时间。关注这些关键部分会产生最高的边际回报。事实证明,循环是Vorbis等媒体算法优化的主要候选者,因为密集数字运算通常发生在它们内部。
还有全局的代码优化方法。首先,编译器可以优化内存保护或速度。此外,可以考虑将函数自动内联到C代码中的汇编指令。 (编译器的inline关键字用于指示函数应该具有在调用点内联生成的代码。这样做可以避免各种成本,例如程序流延迟,函数入口和退出指令以及参数传递开销。)这也会创建在空间和速度之间进行权衡。最后,像Blackfin可用的编译器可以使用两阶段过程来导出单个项目中各种源文件之间的关系,以进一步加快代码执行速度(过程间分析)。
如上所述,大多数媒体算法参考软件都使用浮点运算。但考虑到使用分数定点机器编写的软件仍然错过了一个关键部分。大多数编解码算法的首选语言是C语言,但C语言并不“本地”支持使用分数定点数据。因此,许多分数定点算法都使用整数数学进行仿真。这可能使代码具有高度可移植性,但它不能通过使用特定于机器的编译器构造重写某些数学函数来获得可达到的性能,以获得最高的计算效率。
说明这一点的具体示例如图5.左栏显示了适用于所有整数机器的模拟分数算术的C代码和Blackfin编译器输出。执行32位小数乘法的一次调用需要80个周期。右栏显示了利用(mult_fr1x32x32)可获得的性能改进,这是Blackfin编译器的一个内在函数,它利用了底层的小数硬件。通过这种相当容易的修改,可以实现86%的加速。
系统优化
系统优化以正确的内存布局开始。在最好的情况下,所有代码和数据都适合处理器的L1内存。遗憾的是,这并不总是可行,特别是在网络应用程序中实现大型基于C的应用程序时。
真正的困境是处理器经过优化,可通过直接内存独立于核心移动数据访问(DMA),但MCU程序员通常使用缓存模型运行。虽然核心提取是不可避免的现实,但使用DMA或高速缓存进行大型传输对于保持性能是必不可少的。
为了介绍讨论,让我们考虑Blackfin总线体系结构固有支持的几个属性。第一个是在没有核心干预的情况下仲裁请求的能力。因为内部存储器通常构造在子库中,所以DMA控制器和核心的同时访问可以通过将数据放置在单独的库中而在单个周期中完成。例如,核心可以在一个子库中的数据上操作,而DMA在第二子库中填充新的缓冲器。在某些情况下,也可以同时访问同一个子库。
通常只有一条物理总线可用于访问外部存储器。结果,仲裁功能变得更加关键。下面是一个澄清挑战的示例:在任何给定周期,可以访问外部存储器位置,以便在它作为传入和传出数据的源和目标的同时填充指令缓存。
指令执行
Blackfin处理器使用分层存储器架构,力求平衡具有不同大小和性能级别的多个级别的存储器。片上 L1存储器最接近核心处理器,以全时钟速率工作。该存储器可以配置为SRAM和/或高速缓存。需要最大确定性的应用可以在单核时钟周期内访问片上SRAM。对于需要更大代码尺寸的系统,可提供额外的片上和片外存储器 - 延迟增加。
SDRAM 比L1 SRAM慢,但存储需要大型程序和数据缓冲区。但是,程序员可以通过多种方式利用快速L1内存。如果目标应用程序直接适合L1存储器,除了程序员将应用程序代码直接映射到该存储空间之外,不需要特殊操作 - 如上述Vorbis示例中那样。
如果应用程序代码对于内部存储器而言太大,例如,将网络组件添加到Vorbis编解码器时,可以使用缓存机制来允许程序员访问更大,更便宜的外部存储器。 缓存用作在需要时自动将代码放入L1内存的方法。一旦进入L1,代码就可以在单个核心周期中执行,就像它首先存储在芯片上一样。这个过程的关键优势在于程序员不必管理进出缓存的代码移动。
当执行的代码本质上是线性的时,使用缓存是最好的。指令缓存实际上执行两个角色。首先,它有助于以更有效的方式从外部存储器预取指令。此外,由于高速缓存通常使用某种类型的“最近最少使用”算法运行,因此最常运行的指令通常保留在高速缓存中。因此,如果代码已经被提取一次并且尚未被替换,那么它将在下一次循环时准备好执行。
谨慎的实时程序员没有信任缓存来获得最好的系统性能,因为如果执行需要时指令块不在高速缓存中,系统性能将降低。利用缓存锁定机制可以避免此问题。当关键指令加载到缓存中时,可以锁定缓存行以防止指令被替换。这允许程序员在缓存中保留他们所需的内容,并允许缓存机制本身管理不太重要的指令。此功能使Blackfin处理器与其他信号处理器区别开来。
数据管理
在讨论了如何最好地管理代码以提高此应用程序的性能之后,我们现在考虑数据移动的选项。作为高速缓存的替代方案,可以使用独立于内核的DMA控制器将数据移入和移出L1存储器。虽然内核在一部分内存上运行,但DMA正在引入下一个要处理的数据缓冲区。
Blackfin数据存储器架构对于整体系统性能与指令一样重要 - 时钟速度。由于多媒体应用程序中任何时候都经常发生多次数据传输,因此总线结构必须支持内部和外部存储器的所有区域的核心和DMA访问。至关重要的是自动处理DMA控制器和内核的仲裁,否则性能将大大降低。只需要设置DMA控制器,然后在数据准备好处理时响应中断,就需要进行核心到DMA的交互。此外,数据缓存还可以提高整体性能。
在默认模式下,Blackfin执行数据提取作为基本核心功能。虽然这通常是用于传输数据的最低效机制,但它导致最简单的编程模型。快速暂存器内存通常作为L1内存的一部分提供;但对于较大的片外缓冲区,如果核心必须获取所有内容,则访问时间将受到影响。不仅需要多个周期来获取数据,而且核心也将忙着进行提取。
因此,在可能的情况下,应始终使用DMA来移动数据。 Blackfin处理器具有DMA功能,可在外设和内存之间以及不同内存段之间传输数据。例如,我们的Vorbis实现使用DMA将音频缓冲区传输到音频D / A转换器。
对于此音频应用程序,“旋转门”双缓冲区方案用于容纳DMA引擎。由于串行端口DMA清空了循环双缓冲器的一半,另一半填充有解码的音频数据。为了限制压缩数据被解码的速率,DMA中断服务程序(ISR)修改解码器可以读取的信号量,以确保写入双缓冲区的特定一半是安全的。在缺乏操作系统(OS)的设计中,轮询信号量意味着浪费CPU周期;但是,在操作系统下,调度程序可以切换到另一个任务(如用户界面)以使处理器忙于实际工作。
如果不考虑数据一致性,使用DMA会导致错误的结果。因此,与音频DAC关联的音频缓冲区被放置在非高速缓存的存储空间中,因为除了要由DMA传输的缓冲区之外,高速缓存可能保存的数据版本更新。
装配优化
优化的最后阶段与用汇编语言重写开源C代码的孤立段有关。通过程序集重写提高性能的最佳选择通常是中断服务程序(ISR)和可重用的信号处理模块。
在程序集中编写中断处理程序的动力是低效的ISR会降低其他中断处理程序的响应速度。例如,某些音频设计必须使用音频ISR格式化为音频DAC绑定的AC97数据。由于这种情况会定期发生,因此长音频ISR会降低其他事件的响应速度。减少中断处理程序循环计数的最佳方法是在汇编中重写它。
可重用信号处理模块的一个很好的例子是修改的离散余弦变换(MDCT)用于后端Vorbis处理,将时域信号转换为频域表示。编译器永远不会像熟练的汇编程序员那样生成“紧”的代码,因此MDCT的C版本效率低下。相同功能的汇编版本可以利用Blackfin架构的硬件功能,例如单周期蝶形加/减和硬件位反转。
今天,Vorbis和Speex的Blackfin端口都存在,可根据要求提供。这些端口在ADSP-BF533 EZ-KIT Lite上运行。在blackfin.uclinux.org上也可以找到μClinux的开源端口。它们共同实现了各种各样的应用程序,这些应用程序可以集成免版税的语音或音乐功能,同时保留足够的处理空间以实现其他特性和功能。例如,新的ADSP-BF536和ADSP-BF537及其集成的以太网MAC为低成本的网络音频和语音应用打开了大门。很明显,开源代码预示着嵌入式处理领域的一场革命,Blackfin处理器有望充分利用这种情况。
-
处理器
+关注
关注
68文章
19286浏览量
229842 -
嵌入式
+关注
关注
5082文章
19126浏览量
305201 -
C++
+关注
关注
22文章
2108浏览量
73651
发布评论请先 登录
相关推荐
评论