G.729�(xié)議使用的算法是共軛結(jié)�(gòu)的算�(shù)碼本激�(lì)線性預(yù)�(cè)(CS-ACELP�,它基于CELP編碼模型。由于G.729�解碼�具有很高的語(yǔ)音質(zhì)量和很低的延�(shí),被廣泛地�(yīng)用在�(shù)�(jù)通信的各�(gè)�(lǐng)�,如IP phone和H.323�(wǎng)上多媒體通信系統(tǒng)��
電話線路上的模擬�(yǔ)音信�(hào),�(jīng)話路帶寬濾波(符合ITU-T G.712建議)后,�8kHz采樣,量化�16bit線性PCM�(shù)字信�(hào)輸入到編碼器。該編碼器是基于線性預(yù)�(cè)分析合成技�(shù),盡量減少�(shí)際語(yǔ)音與合成�(yǔ)音之間經(jīng)�(tīng)�(jué)加權(quán)后差分信�(hào)的能量為�(zhǔn)則來(lái)�(jìn)行編碼的。編碼器的結(jié)�(gòu)框圖如圖1所�,其主要部分有�
·線性預(yù)�(cè)分析和LPC系數(shù)的量�;
·�(kāi)�(huán)基音周期估計(jì);
·自適�(yīng)碼本搜索;
·固定碼本搜索;
·碼本增益量化�
下面分別描述這五部分的主要技�(shù)�
·線性預(yù)�(cè)分析與LPC系數(shù)的量�
首先�(duì)信號(hào)�(jìn)行加線性預(yù)�(cè)分析�,分析窗由兩部分組�。部分是半�(gè)漢明�,第二部分是四分之一�(gè)余弦信號(hào)。將加窗后的�(yǔ)音信�(hào)通過(guò)LevinsonDurbin算法獲得線性預(yù)�(cè)濾波器系�(shù)ai i=1......10。由于線譜對(duì)參數(shù)比線性預(yù)�(cè)系數(shù)具有更好的內(nèi)插特性和量化特性[3], G.729將LPC參數(shù)�(zhuǎn)換成相應(yīng)的線譜對(duì)參數(shù),�(duì)線譜�(duì)參數(shù)�(jìn)行量��
·�(kāi)�(huán)基音分析
為了減少自適�(yīng)碼本搜索的復(fù)雜度,需要計(jì)算開(kāi)�(huán)基音Top,使自適應(yīng)碼本搜索在開(kāi)�(huán)基音值附近�(jìn)�?;糁档姆秶�?8~145�(gè)樣本�(diǎn)之間�
·自適�(yīng)碼本搜索
G.729�(duì)每�(gè)子幀�(jìn)行閉�(huán)基音搜索,它通過(guò)最小化原始�(yǔ)音信�(hào)和重�(gòu)�(yǔ)音信�(hào)的加�(quán)均方誤差�(lái)�(jìn)行閉�(huán)基音搜索。對(duì)子幀1的閉環(huán)基音T1的搜索是局限在�(kāi)�(huán)基音Top的一�(gè)小范圍內(nèi),�(duì)子幀2的閉環(huán)基音T2的搜索是局限在閉環(huán)基音T1的一�(gè)小范圍內(nèi)。這樣可以減少基音搜索的復(fù)雜度�
·固定碼本搜索
G.729固定碼本矢量含有四�(gè)非0脈沖,每�(gè)脈沖的幅度要可以�+1�-1。通過(guò)最小化加權(quán)�(yǔ)音信�(hào)和加�(quán)重構(gòu)�(yǔ)音信�(hào)的均方誤差來(lái)�(jìn)行固定碼本的搜索�
·增益量化
G.729�(duì)自適�(yīng)碼本增益和固定碼本增益采用二�(jí)共軛�(jié)�(gòu)碼本�(jìn)行矢量量�。在碼本搜索�(shí),采用�(yù)搜索策略,使得�(yùn)算量只為全搜索算法的1/4�
G.729的解碼也是按幀�(jìn)行的,主要是對(duì)符合G.729�(xié)議的碼流�(jìn)行解�,得到相應(yīng)的參�(shù),根據(jù)�(yǔ)音產(chǎn)生的�(jī)�,合成�(yǔ)�。解碼的方框圖如圖2所�,其主要部分為:參�(shù)解碼;后濾波處��
G.729解碼�(guò)程如下�
·參數(shù)解碼
首先解碼得到線譜�(duì)參數(shù),并將線譜�(duì)參數(shù)�(zhuǎn)換為線性預(yù)�(cè)系數(shù)。然后解碼出基音周期,獲得自適�(yīng)碼本矢量V(n)。解碼出固定碼本矢量的四�(gè)脈沖的位置和符號(hào),�(jì)算出固定碼本矢量c(n)�
·后濾波處�
后濾波處理主要是自適�(yīng)后濾泀自適應(yīng)后置濾波器是由三�(gè)濾波器級(jí)連而成:長(zhǎng)�(shí)后置濾波器Hp(z),短時(shí)后置濾波器Hf(z),頻譜傾斜�(bǔ)償濾波器Ht(z),后面接著�(jìn)行一�(gè)自適�(yīng)增益控制�(guò)�。后� 濾波器的系數(shù)每一�(gè)子幀更新一次。后置濾波能夠有效地改善合成出的�(yǔ)音質(zhì)��
我�?cè)贏nalog Device的定�(diǎn)�(shù)字處理芯片ADSP-2181[4][5]上實(shí)�(shí)�(shí)�(xiàn)了符合ITU-T G.729的全部功�,�(jìn)行編解碼總共用了22MIPS(ADSP-2181處理速度�33MIPS�。實(shí)�(shí)�(shí)�(xiàn)了G.729的編解碼功能,主要有以下的難點(diǎn)�
·�(shù)�(jù)在DSP中的安排。在DSP中只要是聲明的變�,DSP的連接程序就會(huì)分配�(shù)�(jù)空間。如果我們象C�(yǔ)言編程那樣定義局部變�,就會(huì)浪費(fèi)大量的存�(chǔ)空間�
·�(shù)�(jù)精度的處�。在16位的定點(diǎn)信號(hào)處理芯片上實(shí)�(xiàn)一些浮�(diǎn)算法�(shí),為了使運(yùn)算速度加快,往往要針�(duì)定點(diǎn)芯片的特�(diǎn),用定�(diǎn)�(shù)�(lái)表示浮點(diǎn)�(shù)。雖然速度提高�,但是很可能導(dǎo)致運(yùn)算精度不��
·有限�(jì)算資源的利用。ADSP2181只有33MIPS,而且不能使所有的MIPS都用�(lái)�(shí)�(xiàn)G.729的編解碼功能�
·DSP高速運(yùn)行時(shí),DSP與主�(jī)的數(shù)�(jù)交互�
·�(yǔ)音信�(hào)和編解碼緩沖區(qū)的維�(hù)。這些緩沖區(qū)至少都有兩者要去存�(chǔ),如語(yǔ)音信�(hào)緩沖區(qū), 一方面�(yǔ)音編碼模塊要�(diào)�,另一方面采集中斷程序也要�(diào)用它。而在�(yǔ)音編碼模塊調(diào)用的�(guò)程中,該緩沖區(qū)不應(yīng)該被其它模塊所改變,所以中斷程序不�(yīng)該此�(shí)去存�(chǔ)這�(gè)緩沖區(qū),這就存在著矛��
1. 軟件�(shè)�(jì)
軟件�(shè)�(jì)主要包括三�(gè)部分�
· 命令解釋�
命令解釋器主要是用于解釋主CPU�(fā)�(lái)的各種命�,如發(fā)送或接收編解碼數(shù)�(jù)、查詢編解碼狀�(tài)以及啟動(dòng)、停止編解碼操作�。該模塊不直接與主CPU打交�,而是通過(guò)接口功能模塊,間接�(shí)�(xiàn)與主CPU的�(shù)�(jù)信息交換�
· G.729�(shù)�(jù)引擎
我�?cè)贏DSP-2181上完成了G.729的實(shí)�(shí)編/解碼工作�
ADSP-2181不僅包含了ADSP-2100系列的基本結(jié)�(gòu)(三�(gè)�(yùn)算單�、數(shù)�(jù)地址�(fā)生器和一�(gè)程序序列器),還含有兩�(gè)串行�、一�(gè)16位的�(nèi)部IDMA�,一�(gè)8位的BMDA口、一�(gè)可編程定�(shí)�、標(biāo)志輸入輸出(Flag I/O、外部中斷能力以及片�(nèi)程序和數(shù)�(jù)存儲(chǔ)器等周邊�(shè)�。ADSP-2181片內(nèi)集成了共80K字節(jié)的存�(chǔ)�,它們分別是16K字(24bit)程序存�(chǔ)器和16k字(16bit)的�(shù)�(jù)存儲(chǔ)�,大量的片�(nèi)存儲(chǔ)器使得復(fù)雜的G.729編解碼算法能夠全部放入ADSP-2181片內(nèi),�(wú)須增加任何的片外RAM,�(jiǎn)化了硬件�(shè)�(jì)和接口�
· 接口功能模塊
該模塊實(shí)�(xiàn)ADSP-2181與主CPU的數(shù)�(jù)�(shí)際交換工�。該模塊包括DSP的主控程序和�(shù)�(jù)傳輸兩部分。DSP的主控程序主要負(fù)�(zé)不斷將采集到的語(yǔ)音數(shù)�(jù)分幀,送入編碼�,并將接收到的碼流分類后送入解碼器模�。數(shù)�(jù)傳輸部分�(fù)�(zé)采集�(shù)�(jù)和與主CPU的數(shù)�(jù)交換�
2. 硬件�(shè)�(jì)
本系�(tǒng)考慮了各CPU之間的數(shù)�(jù)交換與協(xié)�(diào)等問(wèn)�。ADSP2181具有一�(gè)16位的IDMA
�,在處理器全速運(yùn)行的情況�,ADSP-2181可以自動(dòng)完成IDMA口的接收和發(fā)送數(shù)�(jù),這為系統(tǒng)的設(shè)�(jì)帶來(lái)了很大的便利。利用ADSP-2181的這�(gè)性質(zhì),我們通過(guò)IDMA口來(lái)�(shí)�(xiàn)ADSP-2181與主CPU的數(shù)�(jù)交互�
我�?cè)O(shè)�(jì)了ADSP-2181與PC�(jī)ISA總線接口的主從系�(tǒng)。在這�(gè)主從系統(tǒng)�,PC�(jī)為主CPU,ADSP-2181為從CPU。在啟動(dòng)�(shí),由PC�(jī)通過(guò)IDMA口將程序裝載入ADSP-2181�(nèi)部存�(chǔ)器中。在ADSP-2181全速運(yùn)行時(shí),主機(jī)可以查詢從機(jī)的運(yùn)行狀�(tài)、讀取壓縮后的G.729碼流,也可以送入待解碼的G.729碼流��
在該主從系統(tǒng)�,PC�(jī)通過(guò)ADSP-2181的IDMA口來(lái)讀�(xiě)它的�(nèi)部存�(chǔ)�。PC總線通過(guò)GAL譯碼,形成IACK信號(hào),與ADSP-2181的IDMA口連接,這樣就實(shí)�(xiàn)了在ADSP-2181全速運(yùn)行的情況�,PC�(jī)仍能訪問(wèn)到ADSP-2181�(nèi)部存�(chǔ)��
圖3是主從系�(tǒng)中的ADSP-2181功能與接口的框圖。語(yǔ)音信�(hào)由ADSP1847采集,通過(guò)ADSP-2181的串口0送入到ADSP-2181�(jìn)行編�。編碼數(shù)�(jù)通過(guò)IDMA口送到主機(jī)�(jìn)行存�(chǔ)。需要解碼的�(shù)�(jù)從主�(jī)由IDMA口送到ADSP-2181�(jìn)行解�,解碼后獲得的�(yǔ)音信�(hào)通過(guò)串口0送至ADSP1847�
3 .難點(diǎn)的解�
�(shù)�(jù)在DSP中的安排。維�(hù)好一張變量表,每次�(jìn)入一�(gè)模塊�(shí),首先使用已經(jīng)分配但暫�(shí)不用的變�。只在不夠的情形�,再去分配額外的變�,同時(shí)將這些新分配的變量�(jì)入到變量表中,供其它模塊使用。另外維�(hù)好一�(gè)局部變量堆�,使得各�(gè)模塊的內(nèi)部局部變量分配在堆棧�,�(dāng)從該模塊退出時(shí),就從堆棧中彈出這些局部變�,釋放空間�
�(shù)�(jù)精度的處�。對(duì)精度要求比較高的地方,將計(jì)算的中間變量采用32位來(lái)表示,�(yùn)算結(jié)束后,再轉(zhuǎn)換成16位表�,這樣指令條數(shù)增加不多,但精度卻大大提高�。在某些精度要求比較高的模塊,采用尾數(shù)和指�(shù)�(lái)表示浮點(diǎn)�(shù),自己編寫(xiě)一套指�(shù)和尾�(shù)的運(yùn)算庫(kù),由于尾數(shù)和指�(shù)表示法有足夠大的精度范圍,完全滿足要求。但只能在少許地方采用這種方法,否則�(yùn)算量就會(huì)上去,給實(shí)�(shí)�(shí)�(xiàn)帶來(lái)困難�
有限�(jì)算資源的利用。利用ADSP�(qiáng)大的多功能指令可以非常好地利用有限計(jì)算資��
DSJP高速運(yùn)行時(shí),DSP與主�(jī)的數(shù)�(jù)交互。由于ADSP-2181具有一�(gè)16位的IDMA�,在處理器全速運(yùn)行的情況�,ADSP-2181可以自動(dòng)完成IDMA口的接收和發(fā)送數(shù)�(jù),這為系統(tǒng)的設(shè)�(jì)帶來(lái)了很大的便利。利用ADSP-2181的這�(gè)性質(zhì),我們通過(guò)IDMA口來(lái)�(shí)�(xiàn)ADSP-2181與主CPU的數(shù)�(jù)交互�
�(yǔ)音信�(hào)和編解碼緩沖區(qū)的維�(hù)。本系統(tǒng)的數(shù)�(jù)交互都是采用雙緩沖的工作方式。雙緩沖的好處在于數(shù)�(jù)的交互不�(huì)影響到其他工作的正常�(jìn)��
本系�(tǒng)的數(shù)�(jù)采集與播放采用雙緩沖的工作方�。采集時(shí)采用cod-ad和cod-work兩�(gè)緩沖區(qū),播放�(shí)采用decod-work和decod-work兩�(gè)緩沖區(qū)。cod-ad用于ADSP-2181的串口數(shù)�(jù)采集,cod-work用于ADSP-2181的編�。當(dāng)cod-ad采完一幀�(shù)�(jù)后與cod-work互換。decod-work用于ADSP-2181的串口數(shù)�(jù)播放,decod-work用于ADSP-2181的解�。當(dāng)播放完一幀�(shù)�(jù)�,decod-ad與decod-work互換。采集與播放程序放在ADSP-2181的中斷服�(wù)程序中。本系統(tǒng)只開(kāi)放ADSP-2181的接收中�,ADSP-2181每接收一�(gè)�(shù)�(jù),同時(shí)就播放一�(gè)�(shù)�(jù)�
另外G.729的編碼器的編碼數(shù)�(jù)和解碼器的解碼數(shù)�(jù)都有兩�(gè)緩沖區(qū),緩沖區(qū)的工作原理與�(shù)�(jù)采集和播放的雙緩沖區(qū)的工作原理相同�
綜上所�,ITU-T的G.729�(xié)議是一�(gè)ITU-T�8Kbps�(yǔ)音編解碼�(xié)�,它具有高音質(zhì)和低延時(shí)的特�(diǎn)。軟件設(shè)�(jì)主要包括三�(gè)部分:命令解釋器、G.729�(shù)�(jù)引擎、接口功能模�。我們用ADSP-2181�(shí)�(shí)�(shí)�(xiàn)了G.729�(xié)�,在ADSP-2181的數(shù)�(jù)采集/播放和ADSP-2181與主CPU接口的數(shù)�(jù)交互方面都采用了雙緩沖方�。硬件設(shè)�(jì)主要是通過(guò)ADSP-2181的IDMA�,�(lái)�(shí)�(xiàn)主CPU與ADSP-2181的數(shù)�(jù)交互�
針對(duì)�(shí)�(shí)�(shí)�(xiàn)G.729的一些難�(diǎn),我們提出了一系列解決的方�,通過(guò)這些解決方法,我們已�(jīng)在Analog Device的定�(diǎn)�(shù)字處理芯片ADSP-2181上實(shí)�(shí)�(shí)�(xiàn)了符合ITU-T G.729的全部功�,并且已經(jīng)通過(guò)了ITU-T G.729的全部測(cè)試矢�。該編解碼器已經(jīng)在數(shù)字語(yǔ)音記錄儀和H.323�(wǎng)上多媒體通信系統(tǒng)中推廣應(yīng)��
1. 引言
�(yǔ)音通信是現(xiàn)代多媒體通信中一�(gè)重要的組成部�,語(yǔ)音壓縮又是實(shí)�(xiàn)低速率�(yǔ)音通信的關(guān)鍵技�(shù)。國(guó)際電信聯(lián)盟(ITU)于1996年提出了一種共軛結(jié)�(gòu)代數(shù)碼激�(lì)線性預(yù)�(cè)(CS-ACELP)的�(yǔ)音編碼算法—G.729。該算法�8kbits碼率下具有較好的�(yǔ)音編碼質(zhì)量,且延遲較�,因此在IP電話、移�(dòng)通信、多媒體�(wǎng)�(luò)通信以及各種手持�(shè)備中具有廣泛�(yīng)�。G.729A是在G.729基礎(chǔ)上�(jìn)行了一部分�(jiǎn)化,使得編碼的復(fù)雜度降低,對(duì)硬件的要求更低,而編碼質(zhì)量并�(méi)有明顯降低[1][2][3]�
2.G.729A的DSP軟件�(kāi)�(fā)流程
在編�(xiě)和調(diào)試C6000程序�(shí),為了使C6000代碼獲得的性能,我們需要按照軟件編程的3�(gè)階段�(jìn)行,每�(gè)階段完成的任�(wù)如下[4]�
階段:開(kāi)始可以不考慮C6000的有�(guān)知識(shí),完全根�(jù)任務(wù)編寫(xiě)C�(yǔ)言程序。在CCS�(huán)境下用C6000的代碼產(chǎn)生工�,編譯產(chǎn)生在C6000�(nèi)�(yùn)行的代碼,證明其功能正確。然后再用CCS的調(diào)試工具,如debug和profiler�,分析確定代碼可能存在的、影響性能的低效率�。為�(jìn)一步改�(jìn)代碼性能,需要�(jìn)入第二階��
第二階段:利用內(nèi)�(lián)函數(shù)、CCS編譯選項(xiàng)和其他具體優(yōu)化方法改�(jìn)C�(yǔ)言程序。重�(fù)階段,檢查所�(chǎn)生的C6000代碼性能。如果產(chǎn)生的代碼仍不能達(dá)到所期望的性能,則�(jìn)入第三階段�
第三階段:從C�(yǔ)言程序中抽出對(duì)性能影響很大的程序段,用線性匯編重新編�(xiě),再用匯編優(yōu)化器�(yōu)�,鏈接,直到�(dá)到所期望的性能要求�
具體到G.729A�(biāo)�(zhǔn)編解碼器的實(shí)�(shí)要求,第三階段是工作的重�(diǎn),而且線性匯編的重新編寫(xiě)要求�(duì)程序代碼和DSP的特性有充分的了��
3. G.729A代碼的剖�
CCS集成�(kāi)�(fā)�(huán)境為軟件�(kāi)�(fā)人員提供了高效的�(kāi)�(fā)、調(diào)試工�。特別是它提供了�(píng)�(jià)器( profiler)的�(yōu)化工具,通過(guò)收集在指定代碼區(qū)間程序執(zhí)行的�(tǒng)�(jì)性能,分析確定程序中各�(gè)�、各�(gè)子函�(shù)所花費(fèi)的處理器�(shí)間,從而把程序的優(yōu)化集中在�(duì)程序性能影響的代碼段上去[5]。其兩種不同的測(cè)試方法是�
�1� 在需要測(cè)定復(fù)雜度的程序段的開(kāi)頭和�(jié)尾處�(shè)定兩�(gè)斷點(diǎn),打�(kāi)�(shí)鐘窗口,�(yùn)行程�。在�(gè)斷點(diǎn)處執(zhí)行停止,這時(shí)雙擊�(shí)鐘窗口使之清0,接著繼�(xù)�(zhí)行程�,在第二�(gè)斷點(diǎn)處停�,這時(shí),時(shí)鐘窗口顯示的值便是該段代碼的�(fù)雜度。這在�(cè)試程序中一�(gè)函數(shù)的復(fù)雜度是非常有用的�
?�?� 先打�(kāi)�(tǒng)�(jì)窗口,在需要測(cè)試的程序段頭尾設(shè)置統(tǒng)�(jì)�(diǎn)((Probe Point�。程序運(yùn)行結(jié)束后,統(tǒng)�(jì)窗口�(nèi)該程序段后面的統(tǒng)�(jì)值便是該代碼段的�(fù)雜度。這種方法較簡(jiǎn)�,統(tǒng)�(jì)�(diǎn)自動(dòng)收集�(tǒng)�(jì)信息,無(wú)需手工干涉,這在�(cè)定程序多段代碼的�(fù)雜度是非常有��
4. 線性匯編的�(yōu)�
線性匯編是TI提供的一種匯編語(yǔ)言,其指令系統(tǒng)和匯編語(yǔ)言的指令系�(tǒng)完全相同,但在編�(xiě)�(shí)不需要指定寄存器和操作單�,也不需要考慮延時(shí)的問(wèn)題,因此編寫(xiě)線性匯編相�(duì)要容易一� [6]�
�(jīng)�(guò)階段和第二階段的�(yōu)化后,音頻編碼程序在DM642上的�(yùn)行狀況有了很大改�,但是經(jīng)�(cè)試仍然沒(méi)有到�(dá)�(shí)�(shí)效果,而語(yǔ)言的效率幾乎發(fā)揮到�,測(cè)試的速度�(dá)到了36.5幀/s,是未優(yōu)化之前的10�。這時(shí),我們采用線性匯編語(yǔ)言重新編寫(xiě)C代碼的低效率段程�,�(jìn)一步提高程序的�(zhí)行效率和充分利用DM642的硬件資�,最終按�(shè)�(jì)要求在DM642�(shí)�(shí)�(shí)�(xiàn)G.729A編碼。在前面的DSP�(kāi)�(fā)流程已經(jīng)提過(guò),DSP�(kāi)�(fā)的一�(gè)手段是用匯編重寫(xiě)C代碼,它是可以既提高程序�(zhí)行速度又可以減少程序體積的方法。由于針�(duì)并行處理器編�(xiě)匯編的難度很�,一般采取的是混合編程的方法,即程序的主要部分用C代碼,部分耗時(shí)較大的函�(shù)可以用線性匯編改�(xiě)�
在編�(xiě)線性匯編優(yōu)化代碼的�(guò)程中,為了提高代碼執(zhí)行效�,我們需要遵循以下原則[7]�
?�?)寫(xiě)并行代碼:通過(guò)使用匯編指令并行�(zhí)行的方法減少循環(huán)�(nèi)的執(zhí)行周期數(shù),優(yōu)化線性匯編代�。這里的關(guān)鍵問(wèn)題是弄清指令相關(guān)�,只有不相關(guān)的指令才能并行執(zhí)�。辨別指令是否相�(guān),可以使用相�(guān)圖�
?�?)處理跳�(zhuǎn)指令和轉(zhuǎn)移指令:匯編程序的一大特�(diǎn)就是頻繁地跳�(zhuǎn),當(dāng)滿足不同的條件時(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ù):G.729A的算法實(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í)行�
?�?)展�(kāi)程序體:在一定條件下,盡量展�(kāi)程序,以減少子程序的�(diào)用和返回次數(shù),犧牲空間換取時(shí)間�
G.729A算法中的LPC模塊、LSP量化及激�(lì)碼本搜索耗時(shí)最多,為�(jìn)一步提高代碼效�,對(duì)相關(guān)�(jì)�、FIR濾波等部分函�(shù)用線性匯編語(yǔ)言�(jìn)行了改寫(xiě),并用畫(huà)相關(guān)圖等方法有針�(duì)性的�(jìn)行優(yōu)化。經(jīng)匯編�(yōu)化器�(yōu)化后,代碼效率比C�(yǔ)言直接編譯有明顯提��
5. �(yōu)化工作的�(chuàng)新點(diǎn)
在對(duì)G.729A的優(yōu)化中,本文在前人研究成果的基�(chǔ)�,針�(duì)TMS320DM642 DSP系列芯片提出了一些有�(jià)值的新方法。這些�(chuàng)新點(diǎn)在不同程度上提高了代碼的�(yōu)化速度和執(zhí)行效�,在�(yǔ)音編解碼的DSP�(shí)�(shí)�(shí)�(xiàn)中起到了�(guān)鍵性作�。下�,以舉例的方式闡明一些經(jīng)典的方法�
5.1 繪制分析�,掌握函�(shù)�(jié)�(gòu)
�(duì)于一�(gè)�(yǔ)句較�、結(jié)�(gòu)�(fù)雜的函數(shù),為了充分了解其邏輯�(jié)�(gòu)和語(yǔ)句的相關(guān)性,我們通常采用�(huà)分析圖的方法。分析圖的形式比較靈活,可以根據(jù)具體的情況選用不同的制圖工具。在編寫(xiě)線性匯編的�(shí)候,需要考慮存取�(shù)組中的元�,數(shù)�(jù)打包操作和數(shù)�(jù)相關(guān)性等�(wèn)�,分析圖有助于正確處理這些�(wèn)��
在對(duì)函數(shù)Cor_h_X� )優(yōu)化過(guò)程中,我們遇到了一定的困難,原因在于其中有一�(gè)雙層的循�(huán)�,內(nèi)層的次數(shù)與外層有�(guān),外層的循環(huán)次數(shù)�40,并且循�(huán)�(nèi)部的�(yǔ)句有先后的相�(guān)�。這樣的結(jié)�(gòu)如果用循�(huán)展開(kāi)的方法將�(huì)用到大量的寄存器,數(shù)目超出了64�(gè),需要開(kāi)辟額外的�(nèi)存空間去存放臨時(shí)變量,而讀�(xiě)�(nèi)存會(huì)消耗較多的�(shí)�,因此這樣�(zhí)行效率不�(huì)有充分的提高。對(duì)�,我們利用分析圖描述了函�(shù)中關(guān)鍵代碼的�(shù)組X[ ],h[ ]的使用情�,如�1所示:
�1 cor_h_X� )函�(shù)分析圖(部分�
�1直觀地反映了�(shù)�16位h[ ]�16位X[ ]之間的乘加關(guān)�,從函數(shù)cor_h_X� )中可知,兩�(gè)�(shù)組的乘積之和要對(duì)�(yīng)的保存在臨時(shí)�(shù)�32位Y[ ]�。通過(guò)研究此分析圖,我們發(fā)�(xiàn)h[ ]與X[ ]中的一些元素�(jìn)行乘積和處理之后就不再被使用,那么存�(chǔ)這些元素的寄存器可以存放中間�(jié)果(Y[]的元素),這樣就可節(jié)省寄存器的使用�(gè)�(shù),免去了�(kāi)辟內(nèi)存空間和中間變量的存取指��
�(duì)于函�(shù)cor_h_X� �,利用上述思想編寫(xiě)線性匯編,只需要定�57�(gè)寄存器就可以完成所用的操作,存取指令從1760條優(yōu)化到30條,僅為原來(lái)�1/60。同�(shí)�(zhí)行速度�390072�(gè)�(shí)鐘減少到35871�(gè),降為原�(lái)�1/10�
繪制的分析圖可以包含相關(guān)圖,相關(guān)表等,使資源安排更加合理。該方法在其他函�(shù)的改�(xiě)中也多次使用��
5.2 功能相似的函�(shù)或代碼段合并為一�(gè)函數(shù)
線性匯編在提高代碼效率的同�(shí)也成倍的增加了代碼尺�,以上述cor_h_X� )為�,它在該�(xiě)后代碼尺寸從660條增大到7776條(該數(shù)�(jù)由CCS剖析工具分析所得)。在工程�(yīng)用中,對(duì)于有限的�(nèi)存程序區(qū),我們會(huì)適當(dāng)減少程序占用的空�。合并功能相似的函數(shù)可以�(dá)到這一要求�
在LSP量化處理中,源代碼中給出�2�(gè)LSP選擇函數(shù):Lsp_select_1� )和Lsp_select_2� �,而我們發(fā)�(xiàn)它們具有相同的功能和相似的�(jié)�(gòu),因此,在對(duì)兩者的線性匯編改�(xiě)�,我們只需編寫(xiě)一�(gè)函數(shù)(命名為L(zhǎng)sp_select)即可實(shí)�(xiàn)LSP量化處理中這兩�(gè)模塊的功��
另外,在�(duì)于一些數(shù)組拷�,數(shù)組初始化的代碼,我們同樣可以用此方�,編�(xiě)一�(gè)函數(shù)�(shí)�(xiàn),這樣可以在提高執(zhí)行效率的同時(shí),減少程序占用的�(nèi)存空間�
5.3 多�(gè)循環(huán)合并為一�(gè)循環(huán)
C代碼改寫(xiě)線性匯編的�(shí)�,我們常常會(huì)�(fā)�(xiàn),只要作一些調(diào)整,兩�(gè)或多�(gè)循環(huán)完成的操作完全可以由一�(gè)循環(huán)�(lái)完成。以LPC子模�240�(diǎn)加窗�(yǔ)音的自相�(guān)�(jì)算Autocorr()函數(shù)為例,經(jīng)�(guò)�(yōu)化改�(xiě)的C代碼(部分)如下�
for(i=0; i<L_WINDOW; i++� //�(gè)循環(huán)�
y[i] = (_smpy(x[i], hamwindow[i]�+0x00008000L�>>16;
sum = 1; //避免�0的情�
for(i=0; i<L_WINDOW; i++� //第二�(gè)循環(huán)�
sum = _sadd(sum,_smpy(y[i], y[i]));
這段代碼包含了兩�(gè)for循環(huán),在CCS中直接編譯運(yùn)行并行度很差,利用線性匯編重�(xiě)代碼。我們發(fā)�(xiàn)兩�(gè)循環(huán)體的循環(huán)次數(shù)均為60(L_WINDOW=60�,所處理的數(shù)組不�,并且兩�(gè)循環(huán)�(méi)有相�(guān)�,可以把和第二�(gè)循環(huán)合并成一�(gè)循環(huán)。前者的功能是對(duì)�(yǔ)音信�(hào)�(jìn)行加窗;后者是�(shí)�(xiàn)乘累加(Mac)。兩者合并后采用線性匯編編�(xiě),其代碼如下�
mvk 60,i //�(shè)置循�(huán)次數(shù)
loop1: lddw *ham++,hamih:hamil //hamwindow[]指針
lddw *x++,xih:xil //x[]指針
smpy2 hamil,xil,yi1:yi0 //兩對(duì)16位操作數(shù)相承,并行執(zhí)�
smpy2 hamih,xih,yi3:yi2
sadd yi0,con0x8000,yi0
sadd yi1,con0x8000,yi1
sadd yi2,con0x8000,yi2
sadd yi3,con0x8000,yi3
packh2 yi1,yi0,yl //�(shù)�(jù)打包技�(shù)
packh2 yi3,yi2,yh
stdw yh:yl,*y++ //雙字存取,提高執(zhí)行效�
smpy2 yl,yl,yi1:yi0
sadd sum0,yi1,sum0
sadd sum0,yi0,sum0
smpy2 yh,yh,yi3:yi2
sadd sum0,yi3,sum0
sadd sum0,yi2,sum0
add i,-1,i
[i] b loop1 //把和第二�(gè)循環(huán)合成一�(gè)大循�(huán),減少轉(zhuǎn)移次�(shù)
�(chǎn)生的匯編代碼并行流水性能大大增加,耗費(fèi)的時(shí)鐘周期數(shù)�1310000減少�15000,少于改編前�1/8�
6. �(jié)束語(yǔ)
�(guān)于編解碼器執(zhí)行的�(shí)鐘周�,在線性匯編改�(xiě)前后,文件版本通過(guò)CCS的profiler剖析工具得知:每10幀�100ms)從159700000降至68500000,僅為原�(lái)�42%。硬件版本�(jìn)行測(cè)試得:編解碼的幀�(shù)提高到了88幀/s以上,鑒于編�、解碼的�(shí)間比例為5:1,所�,本系統(tǒng)編碼已經(jīng)�(dá)�100幀/s,完全符合實(shí)�(shí)通信的要��