DSP 優(yōu)化心得資料_第1頁
DSP 優(yōu)化心得資料_第2頁
DSP 優(yōu)化心得資料_第3頁
DSP 優(yōu)化心得資料_第4頁
DSP 優(yōu)化心得資料_第5頁
已閱讀5頁,還剩15頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

DSP優(yōu)化心得

C6XX優(yōu)化經(jīng)驗總結(jié)

一、c6x的編譯的常用選項

(一)c6x的編譯程序為“cl6x.exe”使用的方法

CI6x[options][filenames]

CI6x:編譯程序

Options:編譯選項

Filenames:C或匯編源文件

說明:

編譯選項是一個字母或者兩個字母,對大小寫不敏感。

編譯選項的前面需要有一個“一”符號。

一個字母的選項可以合并在一起。比如“一sgq”與“一s-g-q”相同。

兩個字母的選項如果第一個字母相同也可以合并在一起。比如“一mgt”與“一mg-mt”

相同。

(二)有關(guān)優(yōu)化的選項

-mt:表示在程序中沒有使用alaising技術(shù),這使得編譯器可以進行比較好的優(yōu)化。

-03:對文件級別進行最強的優(yōu)化,一般在編譯時應(yīng)該使用這個選項。但是在個別情況下使用

這個選項優(yōu)化程序可能會出現(xiàn)

錯誤(-。2有相同現(xiàn)象,-o0和-。1不會出現(xiàn)錯誤)??赡苁窃趦?yōu)化循環(huán),組織流水線的時候

發(fā)生錯誤。如果有這種現(xiàn)象出現(xiàn)可以同時

使用-g選項,程序優(yōu)化就不會出現(xiàn)錯誤,但是優(yōu)化效果會卜.降。另外可以調(diào)整程序的表達(dá)方

式,可能會避免編譯器發(fā)生錯誤。

-pm:在程序級別進行優(yōu)化??梢詫⑺晕募?lián)合在一起進行優(yōu)化,主要有去掉沒有被調(diào)用

的函數(shù)、總是常數(shù)的變量以及沒有使用的

函數(shù)返回值。建議由程序員自己進行這種優(yōu)化工作。使用這個選項在win98下編譯可能會

出現(xiàn)找不到編譯程序的情況。

-msO:不使用冗余循環(huán)進行優(yōu)化,減小程序的大小。一般情況下這個選項對程序大小的優(yōu)化

作用不明顯。

-mh[n]:去掉流水線的epilog,減小程序的大小。這個選項的作用比較明顯。但是有可能出

現(xiàn)讀取地址超出有效范圍的問題,

所以要在數(shù)據(jù)段的開始和結(jié)尾處增加一些pading,或者在分配內(nèi)存時保證數(shù)組的前面和后

面一段范圍內(nèi)都是有效的地址。

可選的參數(shù)n給出這種pading的長度字節(jié)數(shù)。

(三)保留編譯和優(yōu)化信息的選項

-k:保留優(yōu)化后生成匯編語言文件。

-s:匯編語言文件中加入優(yōu)化信息,如果沒有則加入C語言源程序作為注釋。

-mw:在匯編語言文件加入軟件流水線信息。

(四)有關(guān)調(diào)試和剖析的選項

-g:允許符號調(diào)試,在文件中包含符號信息和行號信息,可以在c語言級別進行調(diào)試

和剖析。使用聯(lián)合使用一g、一mt和一o3可以保

證能夠進行符號調(diào)試的情況下最大限度的優(yōu)化。

-mg:允許profile優(yōu)化后的程序。在“out”文件中包含符號信息和很少的行號信息。允許

在c語言的函數(shù)基本進行剖析。

如果聯(lián)合使用這兩個選項、一g選項可能被忽略,結(jié)果與只用一mg相同。

(五)其它類型

-mln:生成大內(nèi)存模式的程序。

-mIO:缺省情況下將集合變量(數(shù)組和結(jié)構(gòu))作為far型。

-mil:缺省情況下將全部函數(shù)作為far型

-ml2:等于-mIO加-mil

-ml3:缺省情況下將全部數(shù)據(jù)和函數(shù)作為far型

(六)建議使用的編譯方式

CI6x—gk—mt—o3—mw—ssafilename"

方式1用于程序的調(diào)試,這種方式具有比較強的優(yōu)化能力,并且支持符號調(diào)試。在編譯的過

程中不會發(fā)生錯誤。

由于生成的“out”文件中包含了符號信息和行號信息,所以比較大。

CI6x—k—mgt—o3—mw—ss“filename”

方式2用于程序的剖析(profile),這種方式的優(yōu)化能力兒乎最強(絕大多數(shù)情況下與方式

3相同),

并且支持對程序進行profile。文件中只包含了符號信息前很少的行號信息,所以“。出”文

件比較小。

CI6x—k—mt—o3—mw—ssfilename"

方式3用于最終的發(fā)行版本程序,可以對程序進行最強的優(yōu)化,并且去掉了全部的符號和行

號信息,所以“out”文件比較小。

由多個文件組成的程序應(yīng)該編寫makefile,將編譯參數(shù)放在該文件中,并在其中說明使用的

編譯器的版本號。

(七)連接參數(shù)

—heap:指定堆的大小

-stack:指定棧的大小

連接的各種選項應(yīng)該統(tǒng)?放在“cmd”文件中

二、雙重循環(huán)和多重循環(huán)的優(yōu)化總結(jié)

雙重循環(huán)多重循環(huán)看起來比較復(fù)雜,但實際上多重循環(huán)優(yōu)化方法比較簡單,就在于一個字:

“拆”,一旦完成這一步之后,

多重循環(huán)就成為單層循環(huán),優(yōu)化就可以按照普通的單層循環(huán)來做了。

多重循環(huán)的特點是在優(yōu)化器優(yōu)化時只在最內(nèi)層循環(huán)中形成一個pipeline,這樣循環(huán)語句就不

能充分利用C6的軟件流水線,

而且對于內(nèi)部循環(huán)的次數(shù)較少的情況,消耗在prolog和eplog上的cycle數(shù)也是不可忽視的。

針對這種狀況可以考慮將多重循環(huán)拆開形成一個單層循環(huán),可以拆外層循環(huán)也可以拆內(nèi)層

循環(huán),

一般視具體情況而定。這樣就可以充分利用優(yōu)化器構(gòu)成的Pipeline。如下例:

voidfir2(constshortinput[],constshortcoefs[],shortout[])

inti,j;

intsum=0;

for(i=0;i<40;i++)

(

for(j=0;j<16;j++)

sum+=coefs[j]*inpu1[i+15-j];

out[i]=(sum?15);

)

內(nèi)層循環(huán)循環(huán)次數(shù)較少,運算量也不大,資源方面只占用了一個乘法器,一個cycle只使用

一次乘法器,

而事實上我們可以在一個cycle內(nèi)使用兩個乘法器,所以還可以充分利用另外的一個乘法器。

因此考慮將內(nèi)層循環(huán)拆開來執(zhí)行,如下:

voidfir2_u(constshortinput[],constshortcoefs[],shortout[])

{

inti,j;

intsum;

for(i=0;i<40;i++)

(

sum=coefs[0]*input|i+15];

sum+=coefs[1]*input。+14];

sum+=coefs[2]*input[i+13];

sum+=coefs[3]*input[i+12];

sum+=coefs[4]*input[i+11];

sum+=coefs[5]*input。+10];

sum+=coefs[6]*input[i+9];

sum+=coefs[7]*input[i+8];

sum+=coefs[8]*input[i+7];

sum+=coefs[9]*input[i+6];

sum+=coefs[10]*input[i+5];

sum+=coefs[11]*input[i+4];

sum+=coefs[12]*input[i+3];

sum+=coefs[13]*input。+2];

sum+=coefs[14]*input[i+1];

sum+=coefs[15]*input[i+0];

out[i]=(sum?15);

)

這樣雖然代碼長度增加了,可變成了單循環(huán),所有的運算都參加到pipeline中來,在Piped

loopkernal

中產(chǎn)生每一個cycle內(nèi)都使用了兩個乘法器,充分利用了DSP內(nèi)部的資源,提高了運行效率。

又如下例:

doubl.aReg;

Word3.lvar;

/.(unsigned)low..(unsigned)low.*/

aRe..(double)(0xfff..L_var1..(double)(0xfff..L_var2..2.0;

A>.1.7

aRe..(aRe..65536);

aRe..floor(aReg);

/.(unsigned)low..(signed)high.*/

aRe.+.(double)(0xfff..L_var1..((double)L_shr(L_var2,16)..2.0;

/.(unsigned)low..(signed)high.7

aRe.+.(double)(0xfff..L_var2..((double)L_shr(L_var1,16)..2.0;

A>.1.7

aRe..(aRe..65536);

aRe..floor(aReg);

/.(signed)high..(signed)high.*/

aRe.+.(double)(L_shr(L_var1,16)..(double)(L_shr(L_var2,16)..2.0;

/.saturat.result..*/

lva..L_saturate(aReg);

return(lvar);

)

2、改編后的代碼:

staticinlineWord32LmpyJI(Word32L_var1,Word32Lvar2)

(

Word32aReg_hh;

Word40aReg,aRegJI,aReg_lh,aReg_hl;

aRegJI=(Word40)_mpyu(L_var1,L_var2)?16;

aReg_lh=(Word40)_mpyluhs(L_var1,L_var2);

aReg_hl=(Word40)_mpyhslu(L_var1,L_var2);

aReg_hh=_smpyh(L_var1,L_var2);

aReg=Jsadd(aRegJI,Jsadd(aReg_lh,aReg_hl));

aReg=Jsadd(aReg?15,aReg_hh);

return(_sat(aReg));

)

3.優(yōu)化方法說明:

C6000編譯器提供的intrinsic可快速優(yōu)化C代碼,intrinsic用前下劃線表示同調(diào)用函數(shù)一樣

可以調(diào)用它,即直接內(nèi)聯(lián)為C6000的函數(shù)。

例如,在上例的源代碼中沒有使用intrinsics,每一行C代碼需多個指令周期,在改編后的代

碼中,每一行代碼僅需一個指令周期。

例如,

MaRegJI=(Word40)_mpyu(L_var1,L_var2)?16中“_mpyu”就是一個intrinsics函數(shù),

它表示兩個無符號數(shù)的高16位相乘,

結(jié)果返回。C6000支持的所有intrinsics指令及其功能參見《TMS320c6000系列DSP的

原理與應(yīng)用》一書的第265.266頁,

該書還提供了另外的例子,這些內(nèi)聯(lián)函數(shù)定義在CCS所在的C6000\CGTCKDLS\lncludeU

錄下的C6X.h文件中。

下面這個例子是C6000的“Programmer'sGuide”上提取的使用intrinsics優(yōu)化C代碼的

例子。

源代碼:

intdotprod(constshort*a,constshort*b,unsignedintN)

(

inti,sum=0;

for(i=0;i<N;i++)

sum+=a[i]*b[i];

returnsum;

}

改編后代碼:

intdotprod(constint*a,constint*b,unsignedintN)

(

inti,sum1=0,sum2=0:

for(i=0;i<(N?1);i++)

(

sum1+=_mpy(a[i],b[i]);

sum2+=_mpyh(a[i],b[i]);

)

returnsum1+sum2;

)

技巧:

在C語言的調(diào)試全部通過以后,可以嘗試將盡可能多的語句使用intrinsics函數(shù)加以改編,

尤其在循環(huán)體內(nèi),這種改編可以大幅度減少執(zhí)行時間。

四、

1.源代碼:

voidflrjxdl(shortinput[],shortcoefs[],shortout[])

{

inti,j;

for(i=0;i<40;i++)

(

for(j=O;j<16;j++)

out[i*16+j]=coefs[j]*input[i+15-j];

)

)

2、改編后的代碼:

voidfir_fxd2(constshortinput[],constshortcoefs[],shortout[])

(

for(i=0;i<40;i++)

(

for(j=0;j<16;j++)

out[i*16+j]=coefs[j]*input[i+15-j];

)

3.優(yōu)化方法說明:

C6000編譯器如果確定兩條指令是不相關(guān)的,則安排它們并行執(zhí)行。關(guān)鍵字const可以指

定一個變量或者一個變量的存儲單元保持不變。

這有助于幫助編譯器確定指令的不相關(guān)性。例如上例中,源代碼不能并行執(zhí)行,而結(jié)果改編

后的代碼可以并行執(zhí)行。

4.技巧:

使用const可以限定目標(biāo),確定存在于循環(huán)迭代中的存儲器的不相關(guān)性。

五、

1、源代碼:

voidvecsum(short*sum,short*in1,short*in2,unsignedintN)

(

inti;

for(i=0;i<N;i++)

sum[i]=in1[i]+in2[i];

)

2.改編后的代碼:

voidvecsum6(int*sum,constint*in1,constint*in2,unsignedintN)

{

inti;

intsz=N?2;

_nassert(N>=20):

for(i=0;i<sz;i+=2)

(

sum[i]=_add2(in1[i],in2[i]);

sum[i+1]=_add2(in1[i+1],in2[i+1]);

)

)

3.優(yōu)化方法說明:

源代碼中,函數(shù)變量的定義是short*sum,short*in1,short*in2,改編后的代碼函數(shù)變量是

int*sum,constint*in1,constint*in2,整數(shù)類型由16位改編成32位,這時使用內(nèi)聯(lián)指令

“_add2”一次可以完成兩組16位整數(shù)的

加法,效率提高一倍。注意這里還使用了關(guān)鍵字const和內(nèi)聯(lián)指令_nassert優(yōu)化源代碼。

4.技巧:

用內(nèi)聯(lián)指令_add2._mpyhl、_mpylh完成兩組16位數(shù)的加法和乘法,效率比單純16位數(shù)的

加法和乘法提高一倍。

六、也..else…語句的優(yōu)化

(一)

1.源代碼:

if(sub(Itpg,LTP_GAIN_THR1)<=0)

(

adapt=0;

)

else

(

if(sub(Itpg,LTP_GAIN_THR2)<=0)

(

adapt=1;

)

else

{

adapt=2;

)

)

2.改編后的代碼:

adapt=(ltpg>LTP_GAIN_THR1)+(ltpg>LTP_GAIN_THR2);

(二)

1.源代碼:

if(adapt==0)

{

if(filt>5443)

(

result=0;

)

else

(

if(filt<0)

result=16384;

)

else

(

filt=_sshl(filt,18)?16;//Q15

result=_ssub(16384,_smpy(24660,filt)?16);

)

}

)

else

(

result=0;

)

2.改編后的代碼:

filtl=_sshl(filt,18)?16;

tmp=_smpy(24660,filtli?16;

result=_ssub(16384,tmp*(filt>=0));

result=result*(!((adapt!=0)||(filt>5443)));

(三)

1、源代碼:

staticWord16saturate(Word32L_var1)

(

Word16swOut;

if(L_var1>SWMAX)

{

swOut=SW_MAX;

giOverflow=1;

)

elseif(L_var1<SW_MIN)

(

swOut=SW_MIN;

giOverflow=1;

)

else

swOut=(Word16)L_var1;/*automatictypeconversion*/

return(swOut);

}

2.改編后的代碼:

staticinlineWord32Lshl(Word32a,Word16b)

(

return((Word32)((b)<0?(Word32)(a)?(-(b)):_sshl((a),(b))));

}

3.優(yōu)化方法說明:

如果在循環(huán)中出現(xiàn)if...else...語句,由于if...else...語句中有跳轉(zhuǎn)指令,而每個跳轉(zhuǎn)指令有5

個延遲間隙,

因此程序執(zhí)行時間延長;另外,循環(huán)內(nèi)跳轉(zhuǎn)也使軟件流水受到阻塞。直接使用邏輯判斷語句

可以去除不必要的跳轉(zhuǎn)。

例如在例1的源代碼最多有兩次跳轉(zhuǎn),而改編后不存在跳轉(zhuǎn)。例2和例3同樣也去掉了跳轉(zhuǎn)。

4、技巧:

盡可能地用邏輯判斷語句替代if...else...語句,減少跳轉(zhuǎn)語句。

七、

1.源程序

dm=0x7FFF;

for(j=0;j<nsiz[m];j=add(j,1))

(

if(dO]<=dm)

(

dm=d[j];

jj=j;

)

}

index[m]=jj;

2、優(yōu)化后的程序

dmO=dm1=0x7fff;

d0=(Word16*)&d[0];

d1=(Word16*)&d[1];

#pragmaMUST_ITERA'E(32,256,64);

for(j=0;j<Nsiz;j+=2)

(

nO=*d0;

dO+=2;

n1=*d1;

d1+=2;

if(nO<=dmO)

(

dmO=nO;

jjO=j;

)

if(n1<=dm1)

(

dm1=n1;

Jj1+;

)

}

if(dm1!=dmO)

index[m]=(dm1<dm3)?jj1:jjO;

)

else

{

index[m]=(jj1>jjO)?jj1:jjO;

)

3、優(yōu)化說明

求數(shù)組的最小值程序,優(yōu)化時為了提高程序效率在一個循環(huán)之內(nèi)計算N=1,35.和n=2,4,6...

的最小值,

然后在比較二者的大小以求得整個數(shù)組的最小值。

八、

1、源程序

for(k=0;k<NBPULSE;k++)

(

i=codvec[k];

j=前曬;

index=mult(i,Q15_1_5);

track=sub(i,extract_l(L_shr(L_mult(index,5),1)));

if(j>0)

(

if(i<l_subfr)code[i]=add(code[i],4096);

codvec[k]+=(2*L_SUBFR);

)

else

(

if(i<l_subfr)code[i]=sub(code[i],4096);

index=add(index,16);

)

if(indx[track]<0)

{

indx[track]=index;

)

else

{

if(((indexAindx[track])&16)==0)

(

if(sub(indx[track],index)<=0)

{

indx[track]=shl((indx[track]&16),3)

+shr(extract_l(L_mult((indx[track]&15),NB_P0S)),1)+(index

&15);

)

else

indx[track]=shl((index&16),3)

+shr(extract_l(L_mult((index&15),NB_POS)),1)+(indx[track]

&15);

)

)

else

(

if(sub((indx[track]&15),(index&15))<=0)

{

indx[track]=shl((index&16),3)

+shr(extract_l(L_mult((index&15),NB_POS)),1)+(indx[track]

&15);

)

else

{

indx[track]=shl((indx[track]&16),3)

十shr(extract_l(L_mult((indx[track]&15),NB_POS)),1)十(index&

15);

)

)

)

)

2、優(yōu)化后的程序

for(k=0;k<8;k++)

(

I=codvec[k];

j=sign[i];

index=_smpy(i,6554)?16;

track=i-index*5;

con=(j>0);

codvec[k]=codvec[k]+110*con;

index=index+(!con)*16;

conn=(i<l_subfr);

cono=(j>0)?1:-1;

code[i]=code[i]+4096*conn*cono;

nO=index;

tO=indx[track];

n1=n0&16;

t1=t0&16;

n2=n0&15;

t2=t0&15;

tmpO=(_sshl(n1,19)?16)+n2*NBPOS+t2;

tmp1=(_sshl(t1,19)?16)+t2*NB_POS+n2;

conp=(((n1==t1)&&(t0>n0))||((n1!=t1)&&(t2<=n2)));

tmp=conp*tmpO+(!conp)*tmp1;

if(tO<0)

indx[track]=nO;

else

indx[track]=tmp;

)

3、優(yōu)化說明

源程序中在循環(huán)中含有許多的if結(jié)構(gòu),在優(yōu)化時對if結(jié)構(gòu)首先進行化簡,

再將化簡后的if結(jié)構(gòu)用條件運算表達(dá)式進行改寫,最后使循環(huán)可以Pipeline。

九、

1、源程序

for(i=0;i<n;i++)

(

max=-32767;

for(j=0;j<n;j++)

(

if(sub(tmp2[j],max)>=0)

(

max=tmp2[j];

ix=j;

)

)

tmp2[ix]=-32768;

tmp[i]=ix;

)

2、優(yōu)化后的程序

if(n0>n1){temp=n0;n0=n1;n1=temp;}

if(n1>n2){temp=n1;n1=n2;n2=temp;}

if(n2>n3){temp=n2;n2=n3;n3=temp;}

if(n3>n4){temp=n3;n3=n4;n4=temp;}

if(n0>n1){temp=n0;n0=n1;n1=temp;}

if(n1>n2){temp=n1;n1=n2;n2=temp;}

if(n2>n3){temp=n2;n2=n3;n3=temp;}

if(n0>n1){temp=n0;n0=n1;n1=temp;}

if(n1>n2){returnn1;}

3、優(yōu)化說明

源程序也為一個求中值的問題,由于已知循環(huán)次數(shù)固定為5,因此將循環(huán)展開使用if語句直

接求取中值。

十、

1、源程序

staticWord16Bin2int(Word16no_of_bits,Word16*bitstream)

Word16value,i,bit;

value=0;

for(i=0;i<no_of_bits;i++)

(

value=shl(value,1);

bit=*bitstream++;

if(sub(bit,BIT_1)==0)

value=add(value,1);

)

return(value);

}

for(i=0;i<prmno[mode];i++)

(

prm[i]=Bin2int(bitno[mode][i],bits);

bits+=bitno[mode][i];

}

2.優(yōu)化后的程序

value=0;

bitsp=bits;

bitnop=&bitno[mode][0];

j=*bitnop++;

j1=*bitnop++;

j2=*bitnop++;

j3=*bitnop++;

j4=*bitnop++;

_nassert(loop[mode]>=35);

for(i-0;i<loop[mode];iii)

(

value=value*2+*bitsp++;

j-;

if(j==0)

(

*prm++=value;

value=0;

J=j1;

J1=J2,

j2=j3;

J3=j4;

j4=*bitnop++;

)

)

3.優(yōu)化說明

源程序按照數(shù)據(jù)位流定義取出參數(shù),為雙重循環(huán)結(jié)構(gòu),優(yōu)化中采用重新根據(jù)位流的bit長度

定義循環(huán)次數(shù),

化簡為單重循環(huán),然后優(yōu)化循環(huán),去除boundary,使pipeline的數(shù)目最小。

H^一、copy程序的優(yōu)化

1.源代碼:

Word16i;

for(i=0;i<L;i++)

{

y[i]=x[i];

}

2.改編代碼:

(1)要求數(shù)組長度能被2整除

Word32i;

Word32temp;

int*p1=(int*)&x[0];

int*q1=(int*)&y[0];

for(i=0;i<L/2;i++)

(

temp=*p1++;

*q1++=temp;

}

(2)要求數(shù)組長度能被4整除

Word32i;

Word32tempi,temp2;

Word32*pin1,*pin2,*pout1,*pout2;

pin1=(Word32*)&x[0];

pin2=(Word32*)&x[2];

pout1=(Word32*)&y[0];

pout2=(Word32*)&y[2];

for(i=0;I<L/4;1++)

{

tempi=*pin1;

temp2=*pin2;

pin1+=2;

pin2+=2;

*pout1=tempi;

*pout2=temp2;

pout1+=2;

pout2+=2;

}

3.優(yōu)化方法說明:

把一次循環(huán)拷貝一個word16的數(shù)改為一次循環(huán)拷貝2個word16或4個word16的數(shù)。

4.技巧:

充分利用C6xx一次讀取32位數(shù)的特性,并利用一個指令周期能讀取兩個數(shù)據(jù)的特點。

十二、set_zero程序的優(yōu)化

1.源代碼:

Word16i;

for(i=0;i<L;i++)

x[i]=0;

)

2.改編代碼:

(1)數(shù)組長度能被2整除

Word32i;

int*x1=(int*)&x[0];

for(i=0;i<L/2;i++)

(

*x1++=0;

)

(2)數(shù)組長度能被4整除

Word32i;

int*x1=(int*)&x[0];

int*x2=(int*)&x[2];

for(i=0;i<L/4;i++)

(

*x1=0;

*x2=0;

x1++;

x2++;

x1++;

x2++;

)

3.優(yōu)化方法說明:

把一次循環(huán)為一個word16的數(shù)賦值改為一次為2個或4個word16的數(shù)賦值。

4.技巧:

充分利用C6XX一次讀取32位數(shù)的特點,并利用一個指令周期能讀取兩個數(shù)據(jù)的特點。

十三、32bit數(shù)與16三數(shù)相乘

1.源代碼:

LJmpO=Mac_32_16(L_32,hi1,Io1,Io2);

2.改編代碼:

LJmp0=_sadd(_sadd(_smpyhl(hl32,Io2),

(_mpyus(hl32,Io2)?16)?1),L_32);

3.優(yōu)化方法說明:

hl32是32bit的數(shù),hi1和Io1是16bit的數(shù),且hl32=hi1?16+Io1?1,BPhi1和Io1

分別是hl32的高16位數(shù)和低16位數(shù)。

函數(shù)Mac_32_16(L_32,hi1,Io1,Io2)實現(xiàn)

L_32=L_32+(hi1*lo2)?1+((Io1*lo2)?15)?1

源代碼是把一個32位的數(shù)拆成兩個16位的數(shù)與一個16位的數(shù)相乘,優(yōu)化后的代碼不拆開

32位的數(shù),

直接用32位的數(shù)與16位的數(shù)相乘。運用這種方法必須保證hl32的最低一位數(shù)必須為0,否

則應(yīng)用指令_clr(hl32,0,0)把

最低位清零。

4.技巧:

源代碼中的低16位數(shù)Io1是hl32的低16位右移一位得到的(留出一位符號位)。在與1。2

相乘時乂右移了15位,

所以在改編代碼中右移16位,并且是以無符號數(shù)與1。2相乘。

十四、32bit數(shù)與32bit數(shù)相乘

1.源代碼:

L_tmp=Mac_32(L_32,hi1,Io1,hi2,Io2);

2.改編代碼:

L_tmp=_sadd(_sadd(_smpyh(hl1_32,hl2_32),

(Cmpyhslu(hl1_32,hl2_32)?16)?1)+

((_mpyhslu(hl2_32,hl1_32)?16)?1)),L_32);

3.優(yōu)化方法說明:

兩個32位的數(shù)相乘,不必分成四個16位的數(shù)相乘,直接用32位相乘。其中:

hl1_32=hi1?16+Io1?1,hl2_32=hi2?16+Io2?1。

源代碼實現(xiàn):L_32=L_32+(hi1*hi2)?1+((hi1*lo2)?15+(Io1*hi2)?15)?1

4.技巧:

低16位與高16位相乘時,低16位使用的是無符號數(shù)。

十五、16位除法的優(yōu)化

1.源代碼:

Wordl6div_s(Wordl6var1,Word16var2)〃實現(xiàn)var1/var2

(

Word16var_out=0;

Wordl6iteration;

Word32Lnum=(Word32)var1;

Word32L_denom=(Word32)var2;

for(iteration=0;iteration<15;iteration++)

{

var_out?=1;

L_num?=1;

if(L_num>=L_denom)

(

L_num=L_sub(L_num,L_denom);

var_out=add(var_out,1);

)

)

return(var_out);

)

2.改編代碼:

Wordl6div_s1(Wordl6var1,Wordl6var2)

(

Word32varlint;

Word32var2int;

varlint=var1?16;

var2int=var2?15;

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

var1int=_subc(var1int,var2int);

return(varlint&Oxffff);

}

3.優(yōu)化方法說明:

實現(xiàn)16位的除法,要求被除數(shù)var1和除數(shù)var2都是整數(shù),且var1〈=var2.利用C6XX特

有的指令subc,實現(xiàn)除法的循環(huán)移位相減操作。

4.技巧:

把被除數(shù)和除數(shù)都轉(zhuǎn)換成32位數(shù)來操作,返回時取低15位數(shù)。

十六、C6X優(yōu)化inline舉例:

1、原程序:

for(i-LO_CHAN;i<-HI_CHAN;iii)

(

norm_shift=norm_l(st->ch_noise[i]);

Ltmp=Lshl(st->ch_noise[i],normshift);

normshiftl=norml(st->chenrg[i]);

Ltmp3=L_shl1(st->ch_enrg[i],norm_shift1-1);

Ltmp2=L_divide(Ltmp3,Ltmp);

Ltmp2=L_shr(Ltmp2,27-1+norm_shift1-norm_$hift);//*scaledas27,4*

if(Ltmp2==0)

Ltmp2=1;

Ltmpl=fnLog10(Ltmp2);

Ltmp3=L_add(Ltmp1,LOG_OFFSET-80807124);//*-round(log10(2A4)*2A26*

Ltmp2=L_mult(TEN_S5_10,extract_h(Ltmp3));

if(Ltmp2<0)

Ltmp2=0;

//*0.1875scaledas10,21*

Ltmpl=L_add(Ltmp2,CONST_0_1875_S10_21);

//*tmp/0.3752.667scaledas5,10,Ltmpisscaled15,16

Ltmp=L_mult(extract_h(Ltmp1),CONST_2_667_S5_10);

ch_snr[i]=extract_h(Ltmp);

)

2.優(yōu)化后程序:

〃因循環(huán)體太大,拆成兩個循環(huán)并把相應(yīng)的函數(shù)內(nèi)嵌以使程序能pipeline,

〃用L_div_tmp口保存因拆分而產(chǎn)生的中間變量。

for(i=LO_CHAN;i<=HI_CHAN;i++)

(

//norm_shift=norm_l(st->ch_noise[i]);

norm_shift=_norm(st->ch_noise[i]);

Ltmp=_sshl(st->ch_noise[i],norm_shift);

//normshiftl=norm_l(st->ch_enrg[i]);

norm_shift1=_norm(st->ch_enrg[i]);

//Ltmp3=L_shl1(st->ch_enrg[i],norm_shift1-1);

LLtmpI=st->ch_enrg[i];

LLtmpI=LLtmpI?(norm_shift1+7);

Ltmp3=(Word32)(LLtmp1?8);

Ltmp2=IL_divide(Ltmp3,Ltmp);

//Ltmp2=L_shr(Ltmp2,27-1+norm_shift1-norm_shift);

Ltmp2=(Ltmp2?(27-1+norm_shift1-norm_shift));

if(Ltmp2==0)

Ltmp2=1;

L_div_tmp[i]=Ltmp2;

)

for(i=LO_CHAN;i<=HI_CHAN;i++)

{

Ltmp2=L_div_tmp[i];

Ltmpl=lfnLog10(Ltmp2);

//Ltmp3=L_add(Ltmp1,LOG_OFFSET-80807124);

Ltmp3=_sadd(Ltmp1,LOG_OFFSET-80807124);

//Ltmp2=L_mult(TEN_S5_10,extract_h(Ltmp3));

Ltmp2=_smpy(TEN_S5_10,(Ltmp3?16));

if(Ltmp2<0)

Ltmp2=0;

Ltmpl=_sadd(Ltmp2,CONST_0_1875_S10_21);

//Ltmp=L_mult(extract_h(Ltmp1),CONST_2_667_S5_10);

Ltmp=_smpy((Ltmp1?16),CONST_2_667_S5_10);

//ch_snr[i

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論