

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、C6XX優化經驗總結優化經驗總結一、一、c6xc6x 的編譯的常用選項的編譯的常用選項(一)c6x的編譯程序為cl6x.exe”使用的方法CI6xoptionsfilenamesCI6x:編譯程序Options:編譯選項Filenames:C或匯編源文件說明:編譯選項是一個字母或者兩個字母,對大小寫不敏感。編譯選項的前面需要有一個一”符號。一個字母的選項可以合并在一起。比如一 sgq”與一sgq”相同。兩個字母的選項如果第一個字母相同也可以合并在一起。 比如一mgt”與一mgmt相同。(二)有關優化的選項-mt:表示在程序中沒有使用alaising技術,這使得編譯器可以進行比較好的優化。-03
2、:對文件級別進行最強的優化,一般在編譯時應該使用這個選項。但是在個別情況下使用這個選項優化程序可能會出現錯誤(-o2有相同現象,-o0和-o1不會出現錯誤)。可能是在優化循環,組織流水線的時候發生錯誤。如果有這種現象出現可以同時使用-g選項,程序優化就不會出現錯誤,但是優化效果會下降。另外可以調整程序的表達方式,可能會避免編譯器發生錯誤。-pm:在程序級別進行優化。可以將所以文件聯合在一起進行優化,主要有去掉沒有被調用的函數、總是常數的變量以及沒有使用的函數返回值。 建議由程序員自己進行這種優化工作。 使用這個選項在win98下編譯可能會出現找不到編譯程序的情況。-msO:不使用冗余循環進行優
3、化,減小程序的大小。一般情況下這個選項對程序大小的優化作用不明顯。-mhn:去掉流水線的epilog,減小程序的大小。這個選項的作用比較明顯。但是有可能出現讀取地址超出有效范圍的問題,所以要在數據段的開始和結尾處增加一些pading,或者在分配內存時保證數組的前面和后面一段范圍內都是有效的地址。可選的參數n給出這種pading的長度字節數。(三)保留編譯和優化信息的選項-k:保留優化后生成匯編語言文件。-s:匯編語言文件中加入優化信息,如果沒有則加入C語言源程序作為注釋。-mw:在匯編語言文件加入軟件流水線信息。(四)有關調試和剖析的選項-g:允許符號調試,在“out”文件中包含符號信息和行號
4、信息,可以在c語言級別進行調試和剖析。使用聯合使用一g、一mt和一o3可以保證能夠進行符號調試的情況下最大限度的優化。-mg:允許profile優化后的程序。在“out”文件中包含符號信息和很少的行號信息。允許在c語言的函數基本進行剖析。如果聯合使用這兩個選項,一g選項可能被忽略,結果與只用一mg相同。(五)其它類型-mln:生成大內存模式的程序。一mIO:缺省情況下將集合變量(數組和結構)作為far型。-ml1:缺省情況下將全部函數作為far型-ml2:等于-ml0加-ml1-ml3:缺省情況下將全部數據和函數作為far型(六)建議使用的編譯方式CI6xgkmto3mwss“filename
5、方式1用于程序的調試,這種方式具有比較強的優化能力,并且支持符號調試。在編譯的過程中不會發生錯誤。由于生成的“out”文件中包含了符號信息和行號信息,所以比較大。CI6xkmgt03mwss“filename方式2用于程序的剖析(profile),這種方式的優化能力幾乎最強(絕大多數情況下與方式3相同),并且支持對程序進行profile。文件中只包含了符號信息和很少的行號信息,所以“out”文件比較小。CI6xkmto3mwss“filename方式3用于最終的發行版本程序, 可以對程序進行最強的優化, 并且去掉了全部的符號和行號信息,所以“out文件比較小。由多個文件組成的程序應該編寫mak
6、efile,將編譯參數放在該文件中,并在其中說明使用的編譯器的版本號。(七)連接參數heap:指定堆的大小stack:指定棧的大小連接的各種選項應該統一放在“cmd”文件中二、雙重循環和多重循環的優化總結雙重循環多重循環看起來比較復雜,但實際上多重循環優化方法比較簡單,就在于一個字:拆,一旦完成這一步之后,多重循環就成為單層循環,優化就可以按照普通的單層循環來做了。多重循環的特點是在優化器優化時只在最內層循環中形成一個pipeline,這樣循環語句就不能充分利用C6的軟件流水線,而且對于內部循環的次數較少的情況,消耗在prolog和eplog上的cycle數也是不可忽視的。針對這種狀況可以考慮
7、將多重循環拆開形成一個單層循環,可以拆外層循環也可以拆內層循環,一般視具體情況而定。這樣就可以充分利用優化器構成的Pipeline。如下例:voidfir2(constshortinput,constshortcoefs,shortout)inti,j;intsum=0;for(i=0;i40;i+)for(j=0;j15);內層循環循環次數較少,運算量也不大,資源方面只占用了一個乘法器,一個cycle只使用一次乘法器,而事實上我們可以在一個cycle內使用兩個乘法器, 所以還可以充分利用另外的一個乘法器。因此考慮將內層循環拆開來執行,如下:voidfir2_u(constshortinput
8、,constshortcoefs,shortout)inti,j;intsum;for(i=0;i15);這樣雖然代碼長度增加了,可變成了單循環,所有的運算都參加到pipeline中來,在Pipedloopkernal中產生每一個cycle內都使用了兩個乘法器, 充分利用了DSP內部的資源, 提高了運行效率。又如下例:tot=4;for(k=0;k4;k+)max=0;for(i=k;i44;i+=STEP)s=0;for(j=i;j(Word32)0)max=s;tot=L_add(tot,L_shr(max,1);在這個多層循環中一共有三層循環,而最內層的循環的運算量很小,只有一次乘累加操
9、作,而我們知道C6中一個packet中可以做兩個乘累加運算,所以為了增加內部循環的運算,減少外部循環的層數,我們可以將第一層循環的操作拆開,其負責的運算加入到內部循環中,也就是在內層循環中一次做四次的乘累加運算,這樣將多次操作形成pipeline,提高了運行效率,優化后的C代碼如下:tot=4;max0=0;max1=0;max2=0;max3=0;for(i=0;i16*/aReg=(aReg/65536);aReg=floor(aReg);/*(unsigned)low1*(signed)high2*/aReg+=(double)(Oxffff&L_var1)*(double)L_
10、shr(L_var2,16)*2.0;/*(unsigned)low2*(signed)high1*/aReg+=(double)(Oxffff&L_var2)*(double)L_shr(L_var1,16)*2.0;/*16*/aReg=(aReg/65536);aReg=floor(aReg);/*(signed)high1*(signed)high2*/aReg+=(double)(L_shr(L_var1,16)*(double)(L_shr(L_var2,16)*2.0;/*saturateresult.*/lvar=L_saturate(aReg);return(Ivar
11、);2、改編后的代碼:staticinlineWord32L_mpy_ll(Word32L_var1,Word32L_var2)Word32aReg_hh;Word40aReg,aReg,aReg_lh,aReg_hl;aReg_ll=(Word40)_mpyu(L_va門,L_var2)16;aRegh=(Word40)_mpyluhs(L_var1,L_var2);aReg_hl=(Word40)_mpyhslu(L_var1,L_var2);aReg_hh=_smpyh(L_va門,L_var2);aReg=_lsadd(aRegi_ll,sadd(aRegh,aReg_hl);aReg
12、=sadd(aReg15,aReg_hh);return(_sat(aReg);3、優化方法說明:C6000編譯器提供的intrinsic可快速優化C代碼,intrinsic用前下劃線表示同調用函數一樣可以調用它,即直接內聯為C6000的函數。例如,在上例的源代碼中沒有使用intrinsics,每一行C代碼需多個指令周期,在改編后的代碼中,每一行代碼僅需一個指令周期。例如,“aRegil=(Word40)_mpyu(L_var1,L_var2)16”中“_mpy就是一個intrinsics函數,它表示兩個無符號數的高16位相乘,結果返回。C6000支持的所有intrinsics指令及其功能參見
13、TMS320C6000系列DSP的原理與應用一書的第265、266頁,該書還提供了另外的例子。這些內聯函數定義在CCS所在的C6000/CGTOOLS/Include目錄下的C6X.h文件中。下面這個例子是C6000的“ProgrammersGuide”上提取的使用intrinsics優化C代碼的例子。源代碼:intdotprod(constshort*a,constshort*b,unsignedintN)inti,sum=0;for(i=0;iN;i+)sum+=ai*bi;returnsum;改編后代碼:intdotprod(constint*a,constint*b,unsignedi
14、ntN)inti,sum1=0,sum2=0;for(i=0;i1);i+)sum1+=_mpy(ai,bi);sum2+=_mpyh(ai,bi);returnsum1+sum2;技巧:在C語言的調試全部通過以后,可以嘗試將盡可能多的語句使用intrinsics函數加以改編,尤其在循環體內,這種改編可以大幅度減少執行時間。四、1、源代碼:voidfir_fxd1(shortinput,shortcoefs,shortout)inti,j;for(i=0;i40;i+)for(j=0;j16;j+)outi*16+j=coefsj*inputi+15-j;2、改編后的代碼:voidfir_fx
15、d2(constshortinput,constshortcoefs,shortout)inti,j;for(i=0;i40;i+)for(j=0;j16;j+)outi*16+j=coefsj*inputi+15-j;3、優化方法說明:C6000編譯器如果確定兩條指令是不相關的, 則安排它們并行執行。 關鍵字const可以指定一個變量或者一個變量的存儲單元保持不變。這有助于幫助編譯器確定指令的不相關性。例如上例中,源代碼不能并行執行,而結果改編后的代碼可以并行執行。4、技巧:使用const可以限定目標,確定存在于循環迭代中的存儲器的不相關性。五、1、源代碼:voidvecsum(short*
16、sum,short*in1,short*in2,unsignedintN)inti;for(i=0;i2;_nassert(N=20);for(i=0;isz;i+=2)sumi=_add2(in1i,in2i);sumi+1=_add2(in1i+1,in2i+1);3、優化方法說明:源代碼中,函數變量的定義是short*sum,short*in1,short*in2,改編后的代碼函數變量是int*sum,constint*in1,constint*in2,整數類型由16位改編成32位,這時使用內聯指令“_add2一次可以完成兩組16位整數的加法,效率提高一倍。注意這里還使用了關鍵字cons
17、t和內聯指令_nassert優化源代碼。4、技巧:用內聯指令_add2、_mpyhl、_mpylh完成兩組16位數的加法和乘法,效率比單純16位數的加法和乘法提高一倍。六、六、ifif elsels 語句的優化語句的優化(一)1、源代碼:if(sub(Itpg,LTP_GAIN_THR1)=0)Ida-elseif(sub(ltpg,LTP_GAIN_THR2)LTP_GAIN_THR1)+(ltpgLTP_GAIN_THR2);(二)1、源代碼:if(adapt=0)if(filt5443)result=0;elseif(filt16;/Q15result=_ssub(16384,_smpy
18、(24660,filt)16);elseresult=0;2、改編后的代碼:filt1=_sshl(filt,18)16;tmp=_smpy(24660,filt1)16;result=_ssub(16384,tmp*(filt=0);result=result*(!(adapt!=0)|(filt5443);(三)1、源代碼:staticWord16saturate(Word32L_var1)Word16swOut;if(L_var1SW_MAX)swOut=SW_MAX;giOverflow=1;elseif(L_var1SW_MIN)swOut=SW_MIN;giOverflow=1;e
19、lseswOut=(Word16)L_va門;/*automatictypeconversion*/return(swOut);2、改編后的代碼:staticinlineWord32L_shl(Word32a,Word16b)return(Word32)(b)(-(b):_sshl(a),(b);3、優化方法說明:如果在循環中出現if.else.語句,由于if.else.語句中有跳轉指令,而每個跳轉指令有5個延遲間隙,因此程序執行時間延長;另外,循環內跳轉也使軟件流水受到阻塞。直接使用邏輯判斷語句可以去除不必要的跳轉。例如在例1的源代碼最多有兩次跳轉,而改編后不存在跳轉。例2和例3同樣也去掉了
20、跳轉。4、技巧:盡可能地用邏輯判斷語句替代if.else.語句,減少跳轉語句。七、七、1、源程序dm=0 x7FFF;for(j=0;jnsizm;j=add(j,1)if(dj=dm)dm=dj;jj=j;indexm=jj;2、優化后的程序dm0=dm1=0 x7fff;d0=(Word16*)&d0;di=(Word16*)&d1;#pragmaMUST_ITERATE(32,256,64);for(j=0;jNsiz;j+=2)n0=*d0;d0+=2;n1=*d1;di+=2;if(n0jjO)?jj1:jjO;3、優化說明求數組的最小值程序,優化時為了提高程序效率在
21、一個循環之內計算N=1,3,5和n=2,4,6的最小值,然后在比較二者的大小以求得整個數組的最小值。八、1、源程序for(k=0;k0)if(il_subfr)codei=add(codei,4096);codveck+=(2*L_SUBFR);elseif(il_subfr)codei=sub(codei,4096);index=add(index,16);if(indxtrack0)indxtrack=index;elseif(indexAindxtrack)&16)=0)if(sub(indxtrack,index)=0)indxtrack=shl(indxtrack&1
22、6),3)+shr(extract_l(L_mult(indxtrack&15),NB_POS),1)+(index&15);elseindxtrack=shl(index&16),3)+shr(extract_l(L_mult(index&15),NB_POS),1)+(indxtrack&15);elseif(sub(indxtrack&15),(index&15)=0)indxtrack=shl(index&16),3)+shr(extract_l(L_mult(index&15),15);elseindxtrack
23、=shl(indxtrack&16),3)+shr(extract_l(L_mult(indxtrack&15),2、優化后的程序for(k=0;k16;track=i-index*5;con=(j0);codveck=codveck+110*con;index=index+(!con)*16;conn=(i0)?1:-1;codei=codei+4096*conn*cono;nO=index;tO=indxtrack;nl=n0&16;NB_POS),1)+(indxtrack&NB_POS),1)+(index&15);t1=to&16;n2
24、=nO&15;t2=tO&15;tmpO=(_sshl(n1,19)16)+n2*NB_POS+t2;tmpl=(_sshl(t1,19)16)+t2*NB_POS+n2;conp=(n1=t1)&(tOn0)|(n1!=t1)&(t2=n2);tmp=conp*tmp0+(!conp)*tmp1;if(t00)indxtrack=n0;elseindxtrack=tmp;3、優化說明源程序中在循環中含有許多的if結構,在優化時對if結構首先進行化簡,再將化簡后的if結構用條件運算表達式進行改寫,最后使循環可以Pipeline。九、1、源程序for(i=0;in
25、;i+)max=-32767;for(j=0;j=0)max=tmp2j;ix=j;tmp2ix=-32768;tmpi=ix;2、優化后的程序if(n0n1)temp=n0;n0=n1;n1=temp;if(n1n2)temp=n1;n1=n2;n2=temp;if(n2n3)temp=n2;n2=n3;n3=temp;if(n3n4)temp=n3;n3=n4;n4=temp;if(n0n1)temp=n0;n0=n1;n1=temp;if(n1n2)temp=n1;n1=n2;n2=temp;if(n2n3)temp=n2;n2=n3;n3=temp;if(n0n1)temp=n0;n0
26、=n1;n1=temp;if(n1n2)returnn1;3、優化說明源程序也為一個求中值的問題,由于已知循環次數固定為5,因此將循環展開使用if語句直接求取中值。十、1、源程序staticWord16Bin2int(Word16no_of_bits,Word16*bitstream)Word16value,i,bit;value=0;for(i=0;ino_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=35);for(i=
27、0;iloopmode;i+)value=value*2+*bitsp+;j-;if(j=0)*prm+=value;value=0;j=j1;j1=j2;j2=j3;j3=j4;j4=*bitnop+;3、優化說明源程序按照數據位流定義取出參數,為雙重循環結構,優化中采用重新根據位流的bit長度定義循環次數,化簡為單重循環,然后優化循環,去除boundary,使pipeline的數目最小。十、十、copycopy 程序的優化程序的優化1、源代碼:Word16i;for(i=0;iL;i+)yi=xi;2、改編代碼:(1) 要求數組長度能被2整除Word32i;Word32temp;int*p
28、1=(int*)&x0;int*q1=(int*)&y0;for(i=0;iL/2;i+)temp=*p1+;*q1+=temp;(2) 要求數組長度能被4整除Word32i;Word32temp1,temp2;Word32*pin1,*pin2,*pout1,*pout2;pin1=(Word32*)&x0;pin2=(Word32*)&x2;pout1=(Word32冷&y0;pout2=(Word32冷&y2;for(i=0;iL/4;i+)tempi=*pin1;temp2=*pin2;pin1+=2;pin2+=2;*pout1=tem
29、pi;*pout2=temp2;pout1+=2;pout2+=2;3、優化方法說明:把一次循環拷貝一個word16的數改為一次循環拷貝2個word16或4個word16的數。4、技巧:充分利用c6xx次讀取32位數的特性,并利用一個指令周期能讀取兩個數據的特點。十二、十二、set_zeroset_zero 程序的優化程序的優化1、源代碼:Word16i;for(i=0;iL;i+)xi=0;2、改編代碼:(1)數組長度能被2整除Word32i;int*x1=(int*)&x0;for(i=0;iL/2;i+)*x1+=0;(2)數組長度能被4整除Word32i;int*x1=(int
30、*)&x0;int*x2=(int*)&x2;for(i=0;iL/4;i+)*x1=0;*x2=0;x1+;x2+;x1+;x2+;3、優化方法說明:把一次循環為一個word16的數賦值改為一次為2個或4個word16的數賦值。4、技巧:充分利用C6XX次讀取32位數的特點,并利用一個指令周期能讀取兩個數據的特點。十十三、三、32bit 數與數與 16bit 數相乘數相乘1、源代碼:L_tmp0=Mac_32_16(L_32,hi1,Io1,Io2);2、改編代碼:L_tmp0=_sadd(_sadd(_smpyhl(hl32,Io2),(_mpyus(hl32,Io2)16
31、)vv1),L_32);3、優化方法說明:hI32是32bit的數,hi1和lol是16bit的數,且hI32=hi1vv16+lolvv1,即hi1和lol分別是hI32的高16位數和低16位數。函數Mac_32_16(L_32,hi1,Io1,Io2).實現L_32=L_32+(hi1*lo2)vv1+(Io1*lo2)15)vv1源代碼是把一個32位的數拆成兩個16位的數與一個16位的數相乘,優化后的代碼不拆開32位的數,直接用32位的數與16位的數相乘。運用這種方法必須保證hl32的最低一位數必須為0,否則應用指令_clr(hl32,0,0)把最低位清零。4、技巧:源代碼中的低16位數
32、lol是hl32的低16位右移一位得到的(留出一位符號位)。在與Io2相乘時又右移了15位,所以在改編代碼中右移16位,并且是以無符號數與lo2相乘。十四、十四、32bit 數與數與 32bit 數相乘數相乘1、源代碼:L_tmp=Mac_32(L_32,hi1,lo1,hi2,lo2);2、改編代碼:L_tmp=_sadd(_sadd(_smpyh(hl1_32,hl2_32),(_mpyhslu(hl1_32,hl2_32)16)vv1)+(_mpyhslu(hl2_32,hl1_32)16)vv1),L_32);3、優化方法說明:兩個32位的數相乘,不必分成四個16位的數相乘,直接用32
33、位相乘。其中:hl1_32=hi1v16+lo1v1,hl2_32=hi2v16+lo2v15+(lo1*hi2)15)vv14、技巧:低16位與高16位相乘時,低16位使用的是無符號數。十五、十五、16 位除法的優化位除法的優化1、源代碼:Word16div_s(Word16var1,Word16var2)實現var1/var2Word16var_out=0;Word16iteration;Word32L_num=(Word32)var1;Word32L_denom=(Word32)var2;for(iteration=0;iteration15;iteration+)var_out=1;L
34、_num=L_denom)L_num=L_sub(L_num,L_denom);var_out=add(var_out,1);return(var_out);2、改編代碼:Word16div_s1(Word16var1,Word16var2)Word32var1int;Word32var2int;var1int=var116;var2int=var215;var1int=_subc(var1int,var2int);var1int=_subc(var1int,var2int);var1int=_subc(var1int,var2int);var1int=_subc(var1int,var2in
35、t);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);varlint=_subc(va門int,var2int);varlint=_subc(var1int,var2int);varlint=_subc(var1int,var2int);varlint=_subc(var1int,var2int);return(varlint&Oxffff);3、優化方法說明:
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度特色餐飲品牌商鋪租賃合同規范
- 2025版餐飲店環保設施升級改造工程合同
- 二零二五年度遺體告別儀式鮮花與祭品供應合同
- 社區美發合作協議書范本
- 中院離婚協議書范本
- 家校勸退協議書范本
- 銷售展柜簽約協議書范本
- 2025版知識產權許可使用保證合同參考范本
- 二零二五年倉儲租賃合同樣本(含倉儲物流解決方案)
- 2025版小柜子汽車配件品牌推廣與市場拓展合同
- 料質檢員筆試試題及答案
- 高壓安全知識培訓
- 護士長崗位勝任力培訓心得
- 陜西省西安市經開區2024-2025學年八年級下學期期末學生學業水平質量監測英語試卷(含答案)
- 警察警械使用培訓課件
- 燃氣管道施工重點難點及安全措施
- 初一新生入學教育
- 空間低溫潤滑技術-洞察及研究
- 意式極簡全案設計
- 《成人慢性腎臟病食養指南(2024年版)》解讀
- 聯營協議合同模板電子版
評論
0/150
提交評論