版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 長沙市2024湖南省藥品檢驗檢測研究院招聘第二批編制外工作人員2人筆試歷年參考題庫典型考點附帶答案詳解(3卷合一)
- 通遼市2024內(nèi)蒙古通遼市市直事業(yè)單位選聘工作人員筆試歷年參考題庫典型考點附帶答案詳解(3卷合一)
- 河源市2024廣東河源市紫金縣融媒體中心招聘編外人員1人筆試歷年參考題庫典型考點附帶答案詳解(3卷合一)
- 桂陽縣2024湖南郴州市桂陽縣高素質(zhì)專業(yè)化黨政人才引進30人筆試歷年參考題庫典型考點附帶答案詳解(3卷合一)
- 新疆2024新疆國際醫(yī)療中心(新疆國際醫(yī)院)第一次招聘事業(yè)單位編制內(nèi)工作人員1筆試歷年參考題庫典型考點附帶答案詳解(3卷合一)
- 城步苗族自治縣2024湖南邵陽城步苗族自治縣事業(yè)單位及縣屬國有企業(yè)人才引進23人筆試歷年參考題庫典型考點附帶答案詳解(3卷合一)
- 國家事業(yè)單位招聘2024中國科學(xué)院動物研究所劉山林研究組科研助理崗位招聘1人筆試歷年參考題庫典型考點附帶答案詳解(3卷合一)
- 2025年重慶西部數(shù)智醫(yī)療研究院公開招聘實驗技術(shù)崗、科技創(chuàng)新部助理、青年研究員14人備考題庫完整參考答案詳解
- 中國人民銀行清算總中心所屬企業(yè)城銀清算服務(wù)有限責(zé)任公司2026年校園招聘16人備考題庫及參考答案詳解
- 2025年淮濱縣司法局公開招聘合同制社區(qū)矯正社會工作者12人實施備考題庫及答案詳解1套
- GB/T 2423.65-2024環(huán)境試驗第2部分:試驗方法試驗:鹽霧/溫度/濕度/太陽輻射綜合
- DB11∕T 594.1-2017 地下管線非開挖鋪設(shè)工程施工及驗收技術(shù)規(guī)程 第1部分:水平定向鉆施工
- 家園共育背景下幼兒良好生活習(xí)慣與能力的培養(yǎng)研究
- 《毛遂自薦》成語故事
- 美容行業(yè)盈利分析
- 小班化教學(xué)和合作學(xué)習(xí)
- 《繼發(fā)性高血壓》課件
- 垃圾中轉(zhuǎn)站運營管理投標(biāo)方案
- 數(shù)字媒體與數(shù)字廣告
- 綜合樓裝飾裝修維修改造投標(biāo)方案(完整技術(shù)標(biāo))
- 中藥現(xiàn)代化生產(chǎn)技術(shù)課件
評論
0/150
提交評論