dsp优化心得
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
iPone 的一句大家都耳熟能详的广告词:“一直被模仿,从未被超越” 。笔者认为主要是因为他们掌握着核心的算法和机器的优化策略。因为一般的硬件我们都买的回来,但是能否将该硬件发挥到极致,就会公司之间的差别,因为同样的硬件,如果软件执行的速度不同,那结果就会有很大的差别,所以说:真正的技术是买不来的。
所以,我们进行嵌入式开发的时候,一旦选定了DSP6000系列的芯片,就不能把它当成单片机来用,必须发挥dsp 与众不同,独一无二的性能。也就是说如何调整c 语言才能够适应这么强悍的硬件就是我们考虑的重点内容,即我们应该按照哪种既定的原则去编写C 代码才能够让dsp 真正作为dsp 在工作,发挥到dsp 的优势。
dsp 的优势在于:速度!
所以,dsp 的优化成为一门专业。
所以,我们一定要使自己在dsp 上编写的c 代码高效运行。因为制约运行速度的因素是硬件和软件。因为dsp 一旦选定,硬件也就确定了。所以,我们首先要注意如何提升软件的效率。对于软件来说,一般情况下有3 个优化等级。第一:算法上优化。第二:程序结构上的优化。第三:汇编级的优化。
我们需要的是研究前两个等级的优化。所以,在这篇文章中,我们需要研究的重点有两个:dsp 的硬件结构和在dsp 上如何优化c 代码。
dsp 的硬件结构
关于dsp 硬件结构的特色有几个:哈佛结构,流水线结构,带宽和运算方式的高效等。1.1.1 哈佛结构
哈佛结构的本质属性是数据存储器(RAM存储数据的存储器)和程序存储器(存储指令)分开。Cpu可以一边取指令,一边取数据。这样会极大的提高处理的速度,因为以前是冯诺依曼结构,总线是分时复用的,这样会降低处理的速度。
而且,dsp6000系列是基于VLIW结构的,具体来讲就说CPU可以提取通过程序从程序存储器中一次提取256bit的指令,即CPU可以一次取8条指令放在处理中。加上和8级流水线的配合,相当于8个传统的CPU一起工作。
1.1.2 流水线结构
流水线结构涉及的CPU 单元包括取指令单元(fetch ),分配指令单元(dispatch )和执行指令单元(executive )。
这3 个单元都是和程序存储器相关的,是处理指令的几个单元。首先,程序总线可以一次
从ROM中取到8条32位的指令,通俗点说,就说一次取了8条汇编语句。然后经过取指令单元(4 个步骤,不详述),分配指令单元(2 个步骤),第一个为分配单元,作用是根据指令之间的相关性将这8 条指令再次分成不同大小的执行包,如果两条指令是没有相关的,就可以同时执行,不分先后顺序。第二个为译码单元,即翻译成可以被执行单元处理的码。执行指令单元(根据不同的指令分为5 个步骤)。但8 条指令通过不是一次这4+2+5个步骤,而是在这9 个步骤中都有指令在同时工作。例如第1个取值包在第1 个步骤,第2 个取值包就在第2 个步骤,第3 个取值包就在第3 个步骤,等等。
剩下要讨论的就说最关键的部分:执行指令单元。
执行指令单元有两个处理指令的通路,每个通路都有4个运算单元:L,S,D,
M。所以指令运算单元就有8个。我们所说的8级流水线作业也就是因为执行单元有8 个运算单元。
以上就是软件流水线的硬件结构。这就是最基础最最本质的硬件结构。我们之后要做的所有的软件优化工作都将作用在这些硬件结构上。但对于我们做优化来讲,我们不需要对硬件了解太深,但一定要了解软件流水线工作的硬件是如何工作的。
1.1.3 带宽优势和运算方式优势
1.1.3.1 带宽优势
DSP6000系列能够极大突破速度瓶颈的一个原因就是带宽和运算方式。所谓带宽就是cpu 一次可以访问的数据量。我们前面提过,指令就是操作码,和指令相关的单元就说取指令单元,分配指令单元和执行指令单元。即这些单元就说和程序存储器ROM丁交道的单元。
我们在上面介绍了执行单元的8 个执行指令的运算单元。但还有32数据通路,即在一个
时钟周期内可以从数据存储器RAM中读取32bit的数据。还有32个通用
寄存器(也可以是16 个寄存器对)用来暂时存储操作数。这些寄存器就是和数据存储器RAM 可接打交道的硬件结构。
这里所说的带宽就是我们在从RAM中读取数据的时候,要尽量利用数据通路的宽度,即我们在编写c代码的时候,一定要“想办法”使CPU^次可以读取32位数据到通用寄存器里面(c64 一次可以读取64 位数据到通用寄存器对里面),因为我们一般情况下处理的原始数据都不是很大,尤其是在图像处理的时候,我们一般情况下使用的是0-255(灰度图像)或0-1(二值图像)。即使对这些数据做加减乘除运算,得到的结果也不会超过216。所以,我们一般
情况下可以用LDW从数据存储器RAM中读取两个16位的数据(即用short声明的数据)。所以,一般情况下,我们用short来声明一个数组,然后用LDW来一次读取32位的数据到寄存器中。这样,我们就可以尽量利用数据通路的宽度,这就是所谓的带宽优势。
1.1.3.2 运算方式优势
所谓的运算就说8 个单元可以进行的操作码。再说具体些就是:加法,减法,乘法,除法,移位,跳转,读取,存储等等。
一般情况下,我们在发挥DSP600C芯片带宽优势的同时要注意运算上的优势。例如,我们一次可以读取两个16 位的数据放在一个32 位的通用寄存器里。然后可以用一个双16*16 运算来处理这两个16 位的数据,即我们可以仅仅通过做一次运算就可以进行两个通用寄存器相乘(每个寄存器中的高16 位和低16 位存放的是独立的16 位数据,即两个通用寄存器中有4 个16 位数据),得到的结果就放在一个寄存器对里面。(如A0:A1 组成的寄存器对,总长64 位,即第1 个结果放在A0里面,第2个结果放在A1里面)。
由于我们是在c 语言层次来讨论dsp 的优化,所以我们要在发挥带宽优势的时候使用内联函数。因为我们一旦使用了字存取方式来处理数据,就必然会用到相关的内联函数,这两者是联系起来的。这就是运算方式上的优势。
我们用数据相加来说明运算方式。
传统计算方式上,我们可以一次提取一个16 位数据(放在一个32 位的通用寄存器里),两次就提取两个16 位数据,然后使用一个加法运算,使两个寄存器相
加,结果放在放在一个通用寄存器里。这样一次运算可以使两个16 位的数相加。
如果我们在传统计算方式上进行优化的话,我们可以这样进行,首先使两个数组进行字对齐。然后使用一个字读取的内联函数读取数据,这样可以一次读取两个16 位的数据放在一个寄存器里,两次就可以读取4 个16 位的数据,之后再使用一个可以进行双16 位数据加16 位数据的内联函数来处理这两个通用寄存器。这样的话,我们就可以一次处理两个16 位数据和16 位数据的相加。
下面用汇编指令来说明,MPY酣以一次执行双16bit*16bit 的运算。
The following code:
MPY A0, A1, A2
MPYH A0, A1, A3