《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 嵌入式技術(shù) > 設(shè)計(jì)應(yīng)用 > 用DSP優(yōu)化G.723.1算法
用DSP優(yōu)化G.723.1算法
摘要: 將G.723.1移植到TMS320C64xx后,就可借助TI集成開(kāi)發(fā)工具CCS(Code Composer Studio)的Profile功能來(lái)評(píng)估其各個(gè)子程序或函數(shù)的執(zhí)行運(yùn)算量,,從而把程序的優(yōu)化集中在對(duì)程序性能影響最大的代碼上去,。
關(guān)鍵詞: DSP G.723.1 TMS320C6472 TMS320C64xx
Abstract:
Key words :

 

       1 引言
  G.723.1是刪組織于1996年推出的一種低碼率的語(yǔ)音編碼算法標(biāo)準(zhǔn),也是目前該組織頒布的語(yǔ)音壓縮標(biāo)準(zhǔn)中碼率最低的一種標(biāo)準(zhǔn),。G.723.1主要用于對(duì)語(yǔ)音及其它多媒體聲音信號(hào)的壓縮,目前在一些數(shù)字音視頻傳輸,、高質(zhì)量語(yǔ)音壓縮等系統(tǒng)中都得到廣泛應(yīng)用,。
 
  2 G.723.1算法的復(fù)雜度分析
 
  將G.723.1移植到TMS320C64xx后,就可借助TI集成開(kāi)發(fā)工具CCS(Code Composer Studio)的Profile功能來(lái)評(píng)估其各個(gè)子程序或函數(shù)的執(zhí)行運(yùn)算量,,從而把程序的優(yōu)化集中在對(duì)程序性能影響最大的代碼上去,。
 
  通過(guò)分析可以看出,,在G.723.1的編解碼算法中,碼本搜索所花費(fèi)的運(yùn)算量是比較大的,,如Find_Best(),,F(xiàn)ind_Fcbk(),F(xiàn)ind_Acbk():另外,,在LPC分析和LSP參數(shù)的計(jì)算上也有運(yùn)算量比較大的,,如Comp_Lpc(),Lsp_Qnt(),,Lsp_Svq(),。
 
  3 代碼的優(yōu)化
 
  代碼優(yōu)化的工作有兩大目的:一是執(zhí)行速度提高,實(shí)現(xiàn)實(shí)時(shí),;二是盡量不擴(kuò)大程序體積(Code Size),,使之在內(nèi)存允許的范圍內(nèi)。顯然,,兩者存在一定的矛盾,,當(dāng)今超大規(guī)模集成電路的發(fā)展使RAM資源不再是系統(tǒng)的瓶頸,因此該部分工作的主要任務(wù)是怎樣提高執(zhí)行速度,。代碼的優(yōu)化工作主要在CCS環(huán)境中進(jìn)行,。優(yōu)化的原則是要充分考慮C64xx處理器超長(zhǎng)指令字、多個(gè)運(yùn)算單元和深度流水線(xiàn)的結(jié)構(gòu)特點(diǎn),,以及避免過(guò)多的讀寫(xiě)內(nèi)存指令和程序轉(zhuǎn)移指令,,充分發(fā)揮其強(qiáng)大的運(yùn)算能力。具體方法包括(次序有先后):
 
  3.1基本運(yùn)算集的優(yōu)化
 
  G.723.1算法程序是用定點(diǎn)運(yùn)算完成浮點(diǎn)運(yùn)算,,為了防止定點(diǎn)運(yùn)算時(shí)可能溢出,,許多運(yùn)算需要進(jìn)行飽和判斷,為此程序?qū)iT(mén)定義了基本運(yùn)算集,,實(shí)現(xiàn)諸如飽和加法,、飽和乘法、除法和移位等操作,。在程序中這些操作調(diào)用相當(dāng)頻繁,,經(jīng)CCS的profile工具測(cè)試,基本運(yùn)算函數(shù)集的調(diào)用占用了95%以上的CPU時(shí)間,。因此,,我們要從基本運(yùn)算集的優(yōu)化開(kāi)始。在熟悉掌握C64xx指令集的前提下,,分析基本運(yùn)算集中各個(gè)函數(shù)完成的悉掌握C64xx指令集的前提下,分析基本運(yùn)算集中各個(gè)函數(shù)完成的功能和對(duì)全局變量產(chǎn)生的影響,,用C64xx指令取而代之或加以改編,。其中包括對(duì)跳轉(zhuǎn)和流水線(xiàn)的優(yōu)化討論,、對(duì)乘積的飽和調(diào)整和全局變量OveRFlow的相關(guān)操作。
 
  由于基本運(yùn)算集以函數(shù)形式存在,,兩次跳轉(zhuǎn)f函數(shù)的調(diào)用與返回1必不可少,,將引起流水線(xiàn)的兩次打斷,表現(xiàn)為12個(gè)指令周期的占用,。將這嶁基本運(yùn)算函數(shù)集改成宏的形式,,即將基本運(yùn)算內(nèi)嵌(inline)至lJ調(diào)用程序中,由此町以消除跳轉(zhuǎn)和流水線(xiàn)打斷帶來(lái)的指令周期占用,,提高執(zhí)行速度,。雖然這樣做增加了代碼長(zhǎng)度,多占用了一些內(nèi)存,,但由于基本運(yùn)算函數(shù)體積均較小,,再經(jīng)過(guò)一定的代碼優(yōu)化,在程序體積上的犧牲幾乎町以忽略,。
 
  基本運(yùn)算的函數(shù)定義在BASIC.C文件里面,,如果能夠?qū)@些簡(jiǎn)單甬?dāng)?shù)進(jìn)行內(nèi)聯(lián)指令(intrinsic)的優(yōu)化,就能達(dá)到事半功倍的效果,。內(nèi)聯(lián)指令是匯編指令的直接映射,,具有很高的效率。與此同時(shí)帶來(lái)的一個(gè)問(wèn)題是溢出保護(hù)位Overflow的判斷,,這是基本函數(shù)里用來(lái)標(biāo)識(shí)溢出的全局變量,,它的作用等同于CSR(Control Status Register)寄存器的SAT(Saturation)位,當(dāng)數(shù)據(jù)溢出時(shí),,SAT位被系統(tǒng)自動(dòng)設(shè)置為1,,所以編解碼函數(shù)里對(duì)Overflow的判斷可以轉(zhuǎn)化成對(duì)SAT位的判斷。引用CSR寄存器時(shí)需要在最開(kāi)始的時(shí)候聲明extem cregister volatile ansigned int CSR,。
 
  C64xx指令提供了飽和乘法指令SMPY,,實(shí)現(xiàn)16"16位的乘法與飽和結(jié)果調(diào)整,其執(zhí)行操作如下:
 
  if(cond){
 
  if((src 1*src2<<1)!=0x80000000)
 
  dst=((src 1*src2)<<1),;
 
  else
 
  dst=0x7ffffff,;
 
  }
 
  else
 
  nop; 
 
  將原指令中的乘法指令改為SMPY.就可以完成乘法和飽和調(diào)整兩種計(jì)算,,這樣可以省去飽和調(diào)整3條指令,。與此類(lèi)似,其它的飽和運(yùn)算,,C64xx都提供了相應(yīng)的指令實(shí)現(xiàn),,將普通運(yùn)算指令替換為飽和運(yùn)算指令,飽和結(jié)果調(diào)整部分的運(yùn)算均可以省去,。
     3.2主程序的優(yōu)化
  主程序的優(yōu)化手段主要采用了以下幾種方法:
 
  (1)使用內(nèi)聯(lián)函數(shù)(intrinsics)
 
  內(nèi)聯(lián)函數(shù)是可直接映射為C64xx指令的特殊函數(shù),,它在指令前加上"_”表示,。例如:
 
  #define L_add(L_var1,L_var2)  _sadd(L_var1,,L_var2)
 
  #define L_mult(var1,,vat2)  _smpy(var1,var2)
 
  等,,基本函數(shù)的內(nèi)聯(lián)優(yōu)化需要對(duì)原函數(shù)的定義和內(nèi)聯(lián)指令都比較熟悉,。
 
  使用內(nèi)聯(lián)函數(shù)代替相應(yīng)的C語(yǔ)句是一種非常簡(jiǎn)便高效的優(yōu)化方法。如上面提到的飽和乘法,,在C語(yǔ)句中,。我們通常要使用兩個(gè)嵌套的條件判斷語(yǔ)句來(lái)檢查結(jié)果是否溢出,而指令int_smpy(int a.int b) 則在完成乘b的運(yùn)算后,,再做一次飽和處理,,這樣一條DSP指令就可完成C語(yǔ)言中多條語(yǔ)句才能完成的計(jì)算,可以節(jié)省很多時(shí)鐘周期,。
 
  (2)循環(huán)展開(kāi)(loop—unrolling)
 
  程序中的有很多的雙重循環(huán)和多暈循環(huán)(比如代數(shù)碼本搜索計(jì)算),,由于C64xx優(yōu)化器在優(yōu)化時(shí)只在最內(nèi)層循環(huán)中形成一個(gè)指令流水(最多可以達(dá)到8級(jí)流水),這樣循環(huán)語(yǔ)句就不能充分利用軟件流水線(xiàn),,而且對(duì)于內(nèi)部循環(huán)次數(shù)較少的情況,,消耗在prolog和eplog上的時(shí)鐘周期也不可忽視。針對(duì)這種情況,,一個(gè)有效的辦法就是將雙重或多重循環(huán)展開(kāi),,降低循環(huán)次數(shù)。這樣雖然代碼長(zhǎng)度增加了,,但有更多的運(yùn)算能夠參加到pipeline中,。由于減少了流水線(xiàn)排空和提高了功能單元的利用率,程序執(zhí)行速度會(huì)大大提高,。
 
  (3)減少分支和調(diào)用指令,,減少判斷指令
 
  程序中的分支、調(diào)用以及判斷指令會(huì)引起程序的跳轉(zhuǎn),,而每個(gè)跳轉(zhuǎn)指令都有5個(gè)延遲間隙,。因此延長(zhǎng)了程序執(zhí)行時(shí)間;另外,,循環(huán)內(nèi)跳轉(zhuǎn)也會(huì)使軟件流水受到阻塞,,降低了代碼執(zhí)行效率。優(yōu)化中,,可以使用內(nèi)嵌,、合并判斷語(yǔ)句來(lái)減少判斷次數(shù)或用邏輯指令替代判斷的方法盡可能的消除中斷流水線(xiàn)指令帶來(lái)的影響。
 
  (4)使用字或雙字存取和計(jì)算
 
  C64xx系列DSP是32位CPU,當(dāng)16位數(shù)據(jù)在內(nèi)存中連續(xù)存放時(shí),,可利用uint_amem4(void*ptr)或double & _amemd8 (void*ptr)指令進(jìn)行字或雙字?jǐn)?shù)據(jù)的讀取或存貯,。這樣每次可同時(shí)存取2個(gè)或4個(gè)16位數(shù)據(jù),由于從內(nèi)存執(zhí)行取數(shù)操作需要4個(gè)delay,,所以減少存取次數(shù)可以節(jié)省大量的時(shí)鐘同期;同時(shí),,可利用C64xx指令集中特有的打包指令_pack2(unsigned a,,unsigned b),_packh2(unsigned a,,unsigned b)等將兩個(gè)16位數(shù)打包成一個(gè)32位數(shù),,在進(jìn)行乘、加計(jì)算時(shí)則利用_add 2(int a,,int b),、_mpy2(int a,int b)同時(shí)完成兩組16位數(shù)的加法和乘法,,效率比單純16位數(shù)的加法和乘法提高一倍,。
 
  3.3匯編編程的優(yōu)化
 
  線(xiàn)性匯編是TI提供的一種匯編語(yǔ)言,其指令系統(tǒng)和匯編語(yǔ)言的指令系統(tǒng)完全相同,,但在編寫(xiě)時(shí)不需要指定寄存器和操作單元,,也不需要考慮延時(shí)的問(wèn)題,因此編寫(xiě)線(xiàn)性匯編相對(duì)要容易一些,。
  經(jīng)過(guò)以上的優(yōu)化后,,音頻編碼程序在DM642上的運(yùn)行狀況有了很大改善,但是經(jīng)測(cè)試仍然沒(méi)有到達(dá)可以接收的程度,,而高級(jí)語(yǔ)言的效率幾乎發(fā)揮到了極致,,所以在具體分析耗時(shí)大的模塊特點(diǎn)后,采用線(xiàn)性匯編語(yǔ)言重新編寫(xiě)C代碼的低效率段程序,,迸一步提高程序的執(zhí)行效率,。
 
  編寫(xiě)線(xiàn)性匯編優(yōu)化代碼的過(guò)程中,為了提高代碼執(zhí)行效率,,我們需要遵循以下原則:
  (1)寫(xiě)并行代碼:通過(guò)使用匯編指令并行執(zhí)行的方法減少循環(huán)內(nèi)的執(zhí)行周期數(shù),,優(yōu)化線(xiàn)性匯編代碼。這里的關(guān)鍵問(wèn)題是弄清指令相關(guān)性,,只有不相關(guān)的指令才能并行執(zhí)行,。辨別指令是否相關(guān).可以使用相關(guān)圖。
  (2)處理跳轉(zhuǎn)指令和轉(zhuǎn)移指令:匯編程序的一大特點(diǎn)就是頻繁地跳轉(zhuǎn),,當(dāng)滿(mǎn)足不同的條件時(shí),,要求程序進(jìn)行不同的操作,或跳到相應(yīng)的位置。對(duì)于“大于”,、“大于等于”,、“小于”、“小于等于”等較為接近的邏輯判斷和處理,,應(yīng)慎重對(duì)待,,否則將產(chǎn)生邏輯性錯(cuò)誤,并且很難調(diào)試,。當(dāng)發(fā)生溢出需進(jìn)行相應(yīng)處理時(shí),,這種現(xiàn)象尤為突出。
  (3)盡量減少循環(huán)體內(nèi)的指令數(shù)[7]:G.72.1的算法實(shí)現(xiàn),,有許多是在循環(huán)內(nèi)部完成的,,有些地方如同定碼本搜索過(guò)程中,為了確定四個(gè)非0脈沖的位置和幅度,,還用到了多重循環(huán),。在循環(huán)內(nèi)部,特別是在嵌套較深的循環(huán)內(nèi)部,,減少一條指令可以大大降低程序的操作次數(shù),。例如。對(duì)于一個(gè)每重循環(huán)8次的四重嵌套循環(huán),,在最內(nèi)層循環(huán)每減少一條指令,,整個(gè)程序可以少執(zhí)行84=4096語(yǔ)句。因此在設(shè)計(jì)程序時(shí),,能夠放在循環(huán)體外執(zhí)行的語(yǔ)句.盡量放在循環(huán)體外執(zhí)行,。
  (4)展開(kāi)程序體:盡在一定條件下,盡量展開(kāi)程序,,以減少子程序的調(diào)用和返回次數(shù),,犧牲空問(wèn)換取時(shí)間。
  經(jīng)匯編優(yōu)化器優(yōu)化后,,代碼效率比C語(yǔ)言直接編譯有明顯提高,。
  4 優(yōu)化工作的創(chuàng)新點(diǎn)
 
  在對(duì)G.723.1的優(yōu)化中.本文在前人研究成果的基礎(chǔ)上,針對(duì)DSP C64xx系列芯片提}n了一些有價(jià)值的新方法,。這些創(chuàng)新點(diǎn)在不同程度上提高了代碼的優(yōu)化速度和執(zhí)行效率,,在語(yǔ)音編解碼的DSP實(shí)時(shí)實(shí)現(xiàn)中起到了關(guān)鍵性作用。下面,,本文將以舉例的方式闡明一些經(jīng)典的方法,。 
 
 
  (1)編寫(xiě)連接命令文件.cmd
 
  明確了系統(tǒng)的程序和數(shù)據(jù)映射地址后,編寫(xiě)連接器命令文件將部分調(diào)用次數(shù)較多的函數(shù),、堆棧段,、數(shù)據(jù)段放入內(nèi)存:cmd文件內(nèi)容如下:
 
  一L\evmdm642_echocfg.cmd //連接CCS提供的連接命令文件
 
  SECTIONS
 
  {
 
 ?。畉ahles>SDRAM
 
  .cinit>ISRAM   //將變量初值表放入內(nèi)存
 
  . far >SDRAM
 
 ?。甤onst>ISRAM //將常數(shù)段放入內(nèi)存
 
 ?。畃init>SDRAM
 
  . tin >SDRAM
 
  .text>SDRAM
 
 ?。畉est >ISRAM
 
  }
 
  一levmdm642bsl.lib     //連接庫(kù)文件
 
  一levmdm642_edma_aic23.164    //連接驅(qū)動(dòng)程序的庫(kù)文件
 
  一lc6xlx_edma_mcasp.J64   //連接串口McASP的庫(kù)文件
 
  其中.test是筆者在C程序內(nèi)用#pragma CODE_SECTION或DATA_SECTION自定義的段,。
 
  (2)高速緩沖寄存器Cache的使用
 
  Cache即高速緩存,是位于CPU和片內(nèi)存儲(chǔ)器之間的規(guī)模小速度快的存儲(chǔ)器,。Cache的工作原理是保存CPU中最常用的數(shù)據(jù),。當(dāng)Cache中保存著CPU要讀寫(xiě)的數(shù)據(jù)時(shí),CPU直接訪(fǎng)問(wèn)Cache,。由于Cache的速度與CPU相當(dāng),CPU能在零等待狀態(tài)下迅速地實(shí)現(xiàn)數(shù)據(jù)存取,。只有在Cache中不舍有CPU所需的數(shù)據(jù)時(shí)CPU才去訪(fǎng)問(wèn)片內(nèi)存儲(chǔ)器,。因此Cache的有效利用對(duì)整個(gè)程序速度的提高有著舉足輕重的作用。在主函數(shù)中加入以下代碼,,使Cache使能:
 
  CACHE_clean  (CACHE_L2ALL,0,0};  //清除Cache內(nèi)原有內(nèi)容
 
  CACHE_setL2Mode  (CACHE_64KCACHE),;  //設(shè)置Cache的大小為64K
 
  CACHE_enableCaching  (CACHE_EMIFA_CE00);  //Cache使能
 
  添加以上代瑪后,,測(cè)試速度由原來(lái)的20幀/s提高到了400幀/s,。提高了將近20倍。
 
  5 結(jié)束語(yǔ)
 
  本文詳緇分紹了G.723.1標(biāo)準(zhǔn)的DSP代碼優(yōu)化工作,,重點(diǎn)描述了代碼優(yōu)化的方法和本課題的創(chuàng)新點(diǎn).對(duì)于算法中的一些函數(shù)提出了獨(dú)創(chuàng)性改寫(xiě)方法,。基于線(xiàn)性匯編的優(yōu)化以及Cache的有效利用使本課題的工作取得了顯著成果,,在沒(méi)有降低音質(zhì)的情況下,,實(shí)現(xiàn)了DSP的語(yǔ)音實(shí)時(shí)編解碼。
  本文作者創(chuàng)新點(diǎn):在對(duì)G.723.1的優(yōu)化中,,針對(duì)TMS320DM 642 DSP系列芯片提出了一些有價(jià)值的新方法,。例如:編寫(xiě)連接命令文件.cmd和高速緩沖寄存器Cache的使用。這些創(chuàng)新點(diǎn)在不同程度上提高了代碼的優(yōu)化速度和執(zhí)行效率,,在語(yǔ)音編解碼的DSP實(shí)時(shí)實(shí)現(xiàn)中起到了關(guān)鍵性作用,。
 
此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載,。