dsp优化心得.doc

上传人:飞****9 文档编号:137776116 上传时间:2020-07-11 格式:DOC 页数:10 大小:132KB
返回 下载 相关 举报
dsp优化心得.doc_第1页
第1页 / 共10页
dsp优化心得.doc_第2页
第2页 / 共10页
dsp优化心得.doc_第3页
第3页 / 共10页
dsp优化心得.doc_第4页
第4页 / 共10页
dsp优化心得.doc_第5页
第5页 / 共10页
点击查看更多>>
资源描述

《dsp优化心得.doc》由会员分享,可在线阅读,更多相关《dsp优化心得.doc(10页珍藏版)》请在金锄头文库上搜索。

1、iPone的一句大家都耳熟能详的广告词:“一直被模仿,从未被超越”。笔者认为主要是因为他们掌握着核心的算法和机器的优化策略。因为一般的硬件我们都买的回来,但是能否将该硬件发挥到极致,就会公司之间的差别,因为同样的硬件,如果软件执行的速度不同,那结果就会有很大的差别,所以说:真正的技术是买不来的。所以,我们进行嵌入式开发的时候,一旦选定了DSP6000系列的芯片,就不能把它当成单片机来用,必须发挥dsp与众不同,独一无二的性能。也就是说如何调整c语言才能够适应这么强悍的硬件就是我们考虑的重点内容,即我们应该按照哪种既定的原则去编写C代码才能够让dsp真正作为dsp在工作,发挥到dsp的优势。ds

2、p的优势在于:速度!所以,dsp的优化成为一门专业。所以,我们一定要使自己在dsp上编写的c代码高效运行。因为制约运行速度的因素是硬件和软件。因为dsp一旦选定,硬件也就确定了。所以,我们首先要注意如何提升软件的效率。对于软件来说,一般情况下有3个优化等级。第一:算法上优化。第二:程序结构上的优化。第三:汇编级的优化。我们需要的是研究前两个等级的优化。所以,在这篇文章中,我们需要研究的重点有两个:dsp的硬件结构和在dsp上如何优化c代码。1.1 dsp的硬件结构关于dsp硬件结构的特色有几个:哈佛结构,流水线结构,带宽和运算方式的高效等。1.1.1 哈佛结构哈佛结构的本质属性是数据存储器(R

3、AM:存储数据的存储器)和程序存储器(存储指令)分开。Cpu可以一边取指令,一边取数据。这样会极大的提高处理的速度,因为以前是冯诺依曼结构,总线是分时复用的,这样会降低处理的速度。而且,dsp6000系列是基于VLIW结构的,具体来讲就说CPU可以提取通过程序从程序存储器中一次提取256bit的指令,即CPU可以一次取8条指令放在处理中。加上和8级流水线的配合,相当于8个传统的CPU一起工作。1.1.2 流水线结构 流水线结构涉及的CPU单元包括取指令单元(fetch),分配指令单元(dispatch)和执行指令单元(executive)。这3个单元都是和程序存储器相关的,是处理指令的几个单元

4、。首先,程序总线可以一次从ROM中取到8条32位的指令,通俗点说,就说一次取了8条汇编语句。然后经过取指令单元(4个步骤,不详述),分配指令单元(2个步骤),第一个为分配单元,作用是根据指令之间的相关性将这8条指令再次分成不同大小的执行包,如果两条指令是没有相关的,就可以同时执行,不分先后顺序。第二个为译码单元,即翻译成可以被执行单元处理的码。执行指令单元(根据不同的指令分为5个步骤)。但8条指令通过不是一次这4+2+5个步骤,而是在这9个步骤中都有指令在同时工作。例如第1个取值包在第1个步骤,第2个取值包就在第2个步骤,第3个取值包就在第3个步骤,等等。剩下要讨论的就说最关键的部分:执行指令

5、单元。执行指令单元有两个处理指令的通路,每个通路都有4个运算单元:L,S,D,M。所以指令运算单元就有8个。我们所说的8级流水线作业也就是因为执行单元有8个运算单元。以上就是软件流水线的硬件结构。这就是最基础最最本质的硬件结构。我们之后要做的所有的软件优化工作都将作用在这些硬件结构上。但对于我们做优化来讲,我们不需要对硬件了解太深,但一定要了解软件流水线工作的硬件是如何工作的。1.1.3 带宽优势和运算方式优势1.1.3.1 带宽优势 DSP6000系列能够极大突破速度瓶颈的一个原因就是带宽和运算方式。所谓带宽就是cpu一次可以访问的数据量。我们前面提过,指令就是操作码,和指令相关的单元就说取

6、指令单元,分配指令单元和执行指令单元。即这些单元就说和程序存储器ROM打交道的单元。我们在上面介绍了执行单元的8个执行指令的运算单元。但还有32数据通路,即在一个时钟周期内可以从数据存储器RAM中读取32bit的数据。还有32个通用寄存器(也可以是16个寄存器对)用来暂时存储操作数。这些寄存器就是和数据存储器RAM间接打交道的硬件结构。这里所说的带宽就是我们在从RAM中读取数据的时候,要尽量利用数据通路的宽度,即我们在编写c代码的时候,一定要“想办法”使CPU一次可以读取32位数据到通用寄存器里面(c64一次可以读取64位数据到通用寄存器对里面),因为我们一般情况下处理的原始数据都不是很大,尤

7、其是在图像处理的时候,我们一般情况下使用的是0-255(灰度图像)或0-1(二值图像)。即使对这些数据做加减乘除运算,得到的结果也不会超过216。所以,我们一般情况下可以用LDW从数据存储器RAM中读取两个16位的数据(即用short声明的数据)。所以,一般情况下,我们用short来声明一个数组,然后用LDW来一次读取32位的数据到寄存器中。这样,我们就可以尽量利用数据通路的宽度,这就是所谓的带宽优势。1.1.3.2 运算方式优势所谓的运算就说8个单元可以进行的操作码。再说具体些就是:加法,减法,乘法,除法,移位,跳转,读取,存储等等。一般情况下,我们在发挥DSP6000芯片带宽优势的同时要注

8、意运算上的优势。例如,我们一次可以读取两个16位的数据放在一个32位的通用寄存器里。然后可以用一个双16*16运算来处理这两个16位的数据,即我们可以仅仅通过做一次运算就可以进行两个通用寄存器相乘(每个寄存器中的高16位和低16位存放的是独立的16位数据,即两个通用寄存器中有4个16位数据),得到的结果就放在一个寄存器对里面。(如A0:A1组成的寄存器对,总长64位,即第1个结果放在A0里面,第2个结果放在A1里面)。由于我们是在c语言层次来讨论dsp的优化,所以我们要在发挥带宽优势的时候使用内联函数。因为我们一旦使用了字存取方式来处理数据,就必然会用到相关的内联函数,这两者是联系起来的。这就

9、是运算方式上的优势。我们用数据相加来说明运算方式。传统计算方式上,我们可以一次提取一个16位数据(放在一个32位的通用寄存器里),两次就提取两个16位数据,然后使用一个加法运算,使两个寄存器相加,结果放在放在一个通用寄存器里。这样一次运算可以使两个16位的数相加。如果我们在传统计算方式上进行优化的话,我们可以这样进行,首先使两个数组进行字对齐。然后使用一个字读取的内联函数读取数据,这样可以一次读取两个16位的数据放在一个寄存器里,两次就可以读取4个16位的数据,之后再使用一个可以进行双16位数据加16位数据的内联函数来处理这两个通用寄存器。这样的话,我们就可以一次处理两个16位数据和16位数据

10、的相加。下面用汇编指令来说明,MPY2可以一次执行双16bit*16bit的运算。The following code:MPY A0, A1, A2MPYH A0, A1, A3may be replaced by:MPY2 A0, A1, A3:A2这就是所谓的运算方式上的优势。一定要记得:带宽优势和运算方式优势是同时发挥的。1.2 dsp上如何优化c代码在C代码基础上进行优化的主要目的就是提高代码执行的速度。主要策略就是向dsp6000系列的编译器传递一些优化的信息。这些优化的信息被优化器理解后,就会使编译器将c代码编译成这些优化信息对应的高效汇编指令,如使用LDW,MYPY2等字读取,双

11、16位*16位指令,字对齐,使指令并行执行等。我们在实际工程应用中,主要针对的就说循环的优化,因为循环是影响执行指令速度的最关键因素。我们只要优化了循环,就完成了dsp的优化。优化循环最大的效果就是使循环的每次迭代参加到流水线中。下面我们来讨论优化循环的因素。1.2.1 最重要的因素:循环次数对于一个循环而言,循环次数是最重要的因素,如果能在保证循环功能的情况下减少循环的话(如将16位读取,16位相加改称双16位读取,双16位相加),那么将极大的优化代码。减少循环次数将最大限度的减少该循环的指令。因为从本质上来说,循环次数越多,跳转的次数越多,这样的话CPU处理这些跳转指令的次数越多,负担肯定

12、越大。循环的汇编指令必须有下面两个指令(红色标记):LOOP:循环体SUB B0,1,B0 /B0中为循环次数,每次执行一次循环体,B0减1B0 B LOOP /如果B0中减为0的话,就跳出循环;否则,转到LOOP继续执行所以,我们在c语言中执行循环的时候,要想办法告诉编译器循环体执行的最少次数,这样的话编译器就可以不产生多余的循环。所谓多余的循环(redundant loop)是编译器因为不知道循环的次数,所以在默认的情况下,产生两个版本。一个是编译器假设循环次数小于最小循环次数(minimum trip count)的情况下产生的没有软件流水的循环版本,另一个是编译器假设循环次数大于或者等

13、于最小循环次数的情况下产生的经过软件流水的循环版本。如果我们通过编译指示MUST_ITERATE告诉编译器循环体最少执行的次数,那么编译器就不会产生那个没有软件流水的循环版本,只会产生经过软件流水的循环版本。在这里我们先讨论下minimum trip count的概念。我们在编写一个循环的时候,根据功能会编写循环体的内容,例如:我们在循环体内执行下面的代码:for(i=0;i10;i+)sumi=in1i+in2i;很明显,循环体内执行两个向量的相加,翻译成汇编指令有6条,也就是说一次迭代有6条指令。如果想要将这个循环实现软件流水的话,最大的效果就说是6次迭代都参加到流水线中,形成一个循环核。

14、即连续六个循环体的每一个循环体中都有一个指令参与到循环核里。这就是已经经过软件流水的循环最好的效果。即每次都有结果输出。这里,minimum trip count就说6。所以,一旦一个循环的c代码确定之后,就确定了软件流水需要的最小的循环次数minimum trip count。如果一次循环体中必要的汇编指令有20条。那就是说最少要执行20次才能使8个循环体的指令都参与到循环核内。这要的样的话,最少的循环次数就是20。(这段话是我自己推测的,有待考证)所以,对于一个循环来说,我们最重要的就是通知循环执行的次数。1.2.2 多层循环优化的法宝:循环展开两层及两层以上的循环叫做多层循环。对于多层循

15、环来说,优化的唯一方法就是将循环展开,不管是展开外层循环还是展开内层循环,结果就是变成单循环。这样的话,编译器就可以优化这个循环了。不过循环展开这个工作要我们自己去做。循环展开最关键的是要看看哪层循环次数最小,就展开这层循环。如下面这个双层循环:可以看出,内层循环的循环次数很少,运算量也不大。每个循环之占用了一个M单元用来进行乘法运算,浪费了资源。我们可以将内层循环展开来执行,如下:这样的话,双循环就变成了单循环,而且在每一个cycle里面使用了两个M单元来进行乘法运算。明显的提高了执行的效率。以后,我们在编写程序的时候,要在事先就注意编写程序,使我们需要的双层循环变成单层循环。然后通过检查asm文件,看看资源有没有合理利用,即有没有使资源平衡使用。有一个标准就是:资源使用一定要平衡。如下面所示: Resource Partition: A-side B-side;* .L units 0 0 ;* .S units 2* 1 ;* .D units 2* 2* ;* .M units

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 总结/报告

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号