H.264代码优化
2007-05-24 2:20
H.264的DSP实现流程分为三个阶段:
第一个阶段产生和评估C代码,第二个阶段优化和评估C代码,第三个阶段编写和评估线性汇编。
每个阶段完成任务如下:
第一阶段:首先,产生C代码并进行时间评估。一般情况下,这个阶段的代码性能很低。如果经过评估后,仍然满足不了实时要求的话,需要进入第二个阶段以进一步改进代码性能。
第二阶段:利用优化选项、内联函数以及其它优化方法改进C代码。如果代码仍不能达到所期望的效率,则进入第三阶段。
第三阶段:从C代码中抽出对性能影响大的代码段,用线性汇编重新写这段代码,然后利用汇编优化器优化该代码,直到代码满足要求为止。
优化和评估C代码
代码分析结果显示DCT、IDCT变换、运动估计运算量占程序总运算量的比重很大,因此这部分函数是程序优化的重点。为此,我们通过下述方法对C代码进行了优化:
(1) 对于复杂的运算语句,可以用查找表的方法来实现,以节省耗时。比如:在运算表达式中出现了“/”以及“%”等符号时,可以先按照所有可能的输入计算出所有可能的输出,以后的运算就可以省略而只需要查表得到数值。该方法的本质在于用空间换时间。同样,对于if-else关系到数据运算的选择语句,也可根据具体的情况,采用查找表的方法来实现。
(2) 对于通过查找表编码部分个,可以将相关的码表进行合理的编排,以便运用一条指令可以一次查到需要的数据。同时,尽可能用多位的指令来访问少位的数据。比如:使用int型(32位)访问2个short(16位)型数据,将其分别放在32位寄存器的高16位和低16位字段。这样,可以提高一倍的数据读取效率。同样,像使用int型可一次访问两个short型一样,使用double型访问可一次读2个float型数据(4个int型数据),从而减少对内存的访问次数,从而减少运算耗时。
(3) 在C代码中,使用内联函数替代复杂的C代码。内联函数是可直接映射为C6000指令的特殊函数,使用时同调用其它函数一样调用,同时不会破坏系统环境。内联函数用前下划线(如:函数_add2 (int src1,int src2)表示src1,src2的高低半字分别做有符号加法,返回结果)表示,使用内联函数可快速优化C代码。
(4) 代码中循环越多,执行的效率越低。 因此,我们考虑采用循环展开的方法,将多循环变为少循环,甚至是单循环。即运用消除冗余循环的方法来提高指令并行执行的程度,从而提高代码的执行效率。
(5) 为了进一步提高代码性能,经过评估,找出影响速度的关键 C代码段 (DCT/IDCT变换和运动估计)用线性汇编重新编写。线性汇编是C6000系列DSP所特有的类汇编工具。只需按照C代码的自然顺序,写出线性汇编语句,同时不必考虑功能单元的分配,以及指令的并行性。从而,它比编写纯汇编语句耗时要少,又具有较高的执行效率。如果编写线性汇编仍不能达到指标要求的话,在运用纯汇编编写相关的代码,充分利用C6000 DSP结构以及指令集的特点,尽可能并行其中的非相关语句。从而进一步减少代码的执行时间和提高程序的性能。
存储器的优化
与PC机相比,DSP的程序数据存储空间非常有限。因此,对于视频编解码这种需要处理大量数据的程序而言,必须合理安排数据和程序的存储方式,实现对存储器的优化,以便提高程序执行的效率。否则,大量数据的反复搬移会阻碍程序运行效率的提高。
采取以下方法对存储器进行优化:分析代码,把被反复调用的程序段(如DCT变换和DCT反变换)放在片内程序存储区中,把频繁用到的数据段(如编码表)放在片内数据存储器中,把不常用到的程序和数据段放在片外存储器中,以避免对程序或数据进行不必要的反复搬移。
在H.264程序运行过程中,由于一帧图像的数据量很大,故而将参考帧数据放到片外,需要用到当前块和参考窗数据时,再将它们从外存搬运到内存中,以便提高效率。
2007-05-24 2:20
H.264的DSP实现流程分为三个阶段:
第一个阶段产生和评估C代码,第二个阶段优化和评估C代码,第三个阶段编写和评估线性汇编。
每个阶段完成任务如下:
第一阶段:首先,产生C代码并进行时间评估。一般情况下,这个阶段的代码性能很低。如果经过评估后,仍然满足不了实时要求的话,需要进入第二个阶段以进一步改进代码性能。
第二阶段:利用优化选项、内联函数以及其它优化方法改进C代码。如果代码仍不能达到所期望的效率,则进入第三阶段。
第三阶段:从C代码中抽出对性能影响大的代码段,用线性汇编重新写这段代码,然后利用汇编优化器优化该代码,直到代码满足要求为止。
优化和评估C代码
代码分析结果显示DCT、IDCT变换、运动估计运算量占程序总运算量的比重很大,因此这部分函数是程序优化的重点。为此,我们通过下述方法对C代码进行了优化:
(1) 对于复杂的运算语句,可以用查找表的方法来实现,以节省耗时。比如:在运算表达式中出现了“/”以及“%”等符号时,可以先按照所有可能的输入计算出所有可能的输出,以后的运算就可以省略而只需要查表得到数值。该方法的本质在于用空间换时间。同样,对于if-else关系到数据运算的选择语句,也可根据具体的情况,采用查找表的方法来实现。
(2) 对于通过查找表编码部分个,可以将相关的码表进行合理的编排,以便运用一条指令可以一次查到需要的数据。同时,尽可能用多位的指令来访问少位的数据。比如:使用int型(32位)访问2个short(16位)型数据,将其分别放在32位寄存器的高16位和低16位字段。这样,可以提高一倍的数据读取效率。同样,像使用int型可一次访问两个short型一样,使用double型访问可一次读2个float型数据(4个int型数据),从而减少对内存的访问次数,从而减少运算耗时。
(3) 在C代码中,使用内联函数替代复杂的C代码。内联函数是可直接映射为C6000指令的特殊函数,使用时同调用其它函数一样调用,同时不会破坏系统环境。内联函数用前下划线(如:函数_add2 (int src1,int src2)表示src1,src2的高低半字分别做有符号加法,返回结果)表示,使用内联函数可快速优化C代码。
(4) 代码中循环越多,执行的效率越低。 因此,我们考虑采用循环展开的方法,将多循环变为少循环,甚至是单循环。即运用消除冗余循环的方法来提高指令并行执行的程度,从而提高代码的执行效率。
(5) 为了进一步提高代码性能,经过评估,找出影响速度的关键 C代码段 (DCT/IDCT变换和运动估计)用线性汇编重新编写。线性汇编是C6000系列DSP所特有的类汇编工具。只需按照C代码的自然顺序,写出线性汇编语句,同时不必考虑功能单元的分配,以及指令的并行性。从而,它比编写纯汇编语句耗时要少,又具有较高的执行效率。如果编写线性汇编仍不能达到指标要求的话,在运用纯汇编编写相关的代码,充分利用C6000 DSP结构以及指令集的特点,尽可能并行其中的非相关语句。从而进一步减少代码的执行时间和提高程序的性能。
存储器的优化
与PC机相比,DSP的程序数据存储空间非常有限。因此,对于视频编解码这种需要处理大量数据的程序而言,必须合理安排数据和程序的存储方式,实现对存储器的优化,以便提高程序执行的效率。否则,大量数据的反复搬移会阻碍程序运行效率的提高。
采取以下方法对存储器进行优化:分析代码,把被反复调用的程序段(如DCT变换和DCT反变换)放在片内程序存储区中,把频繁用到的数据段(如编码表)放在片内数据存储器中,把不常用到的程序和数据段放在片外存储器中,以避免对程序或数据进行不必要的反复搬移。
在H.264程序运行过程中,由于一帧图像的数据量很大,故而将参考帧数据放到片外,需要用到当前块和参考窗数据时,再将它们从外存搬运到内存中,以便提高效率。