如何将汇编语言与C语言整合至DSP

来源:www.vip998.com  作者:本站整理
如何将汇编语言与C语言整合至DSP
摘要:本文将讨论如何将汇编语言程序代码整合到C语言中,以最大化性能以及程序设计人员生产力,内容涵盖了编译器惯例(convention)、内嵌(inlining)、内嵌函数(intrinsic)、缓存器连结(register binding)和除错策略。…

内存扇区属性。预设状态下,编译器将全域C变量和函数分配到标准的预定义内存扇区,该扇区属性允许程序设计人员将上述变量和函数分配到特殊的使用者定义内存扇区。在随后的连结阶段,这些内存扇区可以被映像到具体的内存地址。该功能可让程序设计人员将C语言层级单元分配到实际的内存位置,这对 DSP应用程序来说至关重要。

使用者定义呼叫惯例。如上所述,编译器有一个汇编程序设计人员必须遵守的预定义呼叫惯例;然而在某些情况下,汇编语言函数可利用不同的呼叫惯例获得更佳的最佳化效果。例如,编译器理论上会在累加器中传递参数。若执行延伸地址计算的函数能接收地址缓存器中的参数,那么它的效率会更高。该功能会依靠附加在函数原型的专用语法,并通知修正后的呼叫惯例编译器。

编译器内嵌函数。意指能够用专用的宏或函数呼叫,触发内建编译器功能的总称。例如,CEVA-X和CEVA-TeakLite-III编译器可为语音编码器中常见的ETSI/ITU基本DSP作业,提供编译器内嵌函数。针对这些作业,编译器可利用其等效高度最佳化汇编语言序列,取代每个基本作业。

相反地,没有内嵌函数支持的编译器必须呼叫使用者定义的函数,这样做会导致两大性能缺陷:首先,使用者定义函数可能会在一个回路里产生函数呼叫和返回(如图4),因此产生了巨额的开销;其次,使用者定义函数将如同其它C语言程序代码一样被编译,这意味着使用者定义函数可能会获得次要的最佳化性能。而另一方面,具有内嵌函数的编译器已经内建了最佳化的实作。

图4:H.264编码器——一个关键的函数性能案例。

图4说明了这个功能的重要性。在图4中,左边的C语言程序代码使用ETSI的mult_r(循环相乘)基本作业,CEVA-TeakLite-III编译器产成了如右边的高效实作结果。mult_r作业在左边的C语言程序代码和右边的汇编程序码中以紫色标示。

汇编语言内嵌函数。汇编语言内嵌函数是将汇编程序码内嵌到C语言程序代码的一种先进方法,详细介绍如下。

汇编语言内嵌函数——将汇编语言指令当作C语句一样编写

上述内嵌汇编语言功能具有显著的缺点:

1. 它会破坏各种编译器的最佳化作业,由于编译器不了解内嵌程序代码的内容,因此会使用最坏的假设。

2. 它可能迫使程序设计人员处理低阶问题,如缓存器分配和指令排程。

汇编语言内嵌函数功能可以帮助程序设计人员实现内嵌汇编程序码,且不会产生上述缺点。从程序设计人员的角度来看,汇编语言内嵌函数就像是C语言宏或函数,它们会在呈现一个单一汇编语言指令时,接收C语言层级变量并返回C语言输出结果。由于涉及该功能的所有程序代码都在C语言层级,因此程序设计人员不必担心缓存器分配、指令排程和其它低级语言问题。汇编语言内嵌函数不仅不会妨碍编译器最佳化作业,还会参与最佳化过程,就好像是编译器固定产生的汇编语言指令一样,这些特性造就了强大的汇编语言内嵌函数功能。

利用汇编语言内嵌函数,程序设计人员可以从特殊汇编语言指令中受益,这些指令不太可能从编译器中产生,且通常是为特定算法量身定做的。在适当的位置采用这些指令可以大幅提高性能;例如,CEVA-X1641的bitrev指令就是为FFT等算法定制的。由于编译器不太可能把一个程序看作FFT而使用bitrev指令,因此程序设计人员只需将bitrev汇编语言内嵌函数嵌入到C语言程序代码中。

结合程序设计人员对应用程序的专业知识,汇编语言内嵌函数功能也相继提升。利用这种专业知识,程序设计人员可将精密的汇编语言序列内嵌函数用在 C应用程序中的关键性能区域里。这样一来,程序设计人员便能确保编译器产生的汇编程序码效率就如同手动编写的程序代码一样高。

图5是使用汇编语言内嵌函数与CEVA-X1641编译器的例子。左边的C语言函数使用st(储存,以红色标示)和msu(乘法和减法,以紫色标示)汇编语言内嵌函数。st内嵌函数参与判断(标示为蓝色)和延迟时隙填充(标示为绿色);msu内嵌函数则参与回路解开(标示为橙色)和Quad- Mac(标示为紫色)。汇编语言内嵌函数还受益于由CEVA-X1641编译器处理的所有机械相关问题,如缓存器分配、指令排程和硬件单元分配。

图5:CEVA-X1641编译器支持汇编语言内嵌函数的使用。

【相关文章】好搜一下
Squid 学习笔记

Squid 学习笔记

本文以Redhat Enterprice Linux 4.0版本为基础,并成功实…