<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 牛人業(yè)話 > DSP編程技巧之29---答疑解惑哪家強(qiáng)之(4)

          DSP編程技巧之29---答疑解惑哪家強(qiáng)之(4)

          作者:paradoxfx 時(shí)間:2014-12-08 來源:電子產(chǎn)品世界 收藏

            答疑解惑哪家強(qiáng)?當(dāng)屬我們EEPW最強(qiáng)。。。接下來繼續(xù)我們的答疑解惑。

          本文引用地址:http://www.ex-cimer.com/article/266495.htm

            22. 除了使用編譯器的優(yōu)化選項(xiàng)之外,還可以使用什么方法提高程序的性能?

            編譯器的優(yōu)化選項(xiàng),只能在代碼滿足眾多選項(xiàng)的要求時(shí),才能得到較好的優(yōu)化效果。在我們編程的時(shí)候,首先要做到心里有數(shù),盡可能使用一些高效的編程方式,例如使用右移操作代替除以2的倍數(shù)的操作,可以大幅度地減少代碼運(yùn)行時(shí)間等。這些技巧很多是與的熟練使用所相關(guān)的。此外,根據(jù)器件的特點(diǎn),例如是否包含F(xiàn)PU、CLA等,把特定的代碼放在不同的區(qū)域執(zhí)行,也能起到提高程序性能的效果;根據(jù)代碼對性能的要求,把它們運(yùn)行在不同的位置,例如RAM快于,又快于XINTF等;在器件包含數(shù)學(xué)表的情況下,使用內(nèi)建的數(shù)序函數(shù)庫,而不是標(biāo)準(zhǔn)的C數(shù)學(xué)庫等。在此我們可以給出一些提示:

            1) 代碼運(yùn)行在

            一定要使能預(yù)讀緩沖區(qū),并配置適當(dāng)?shù)牡却隣顟B(tài)。一般在各個(gè)器件的頭文件與外設(shè)示例包里都有對應(yīng)的例子。

            2) 把時(shí)間關(guān)鍵的代碼和/常數(shù)數(shù)組等從Flash復(fù)制到RAM中運(yùn)行

            在RAM中運(yùn)行時(shí),最大的指令周期比Flash中運(yùn)行時(shí)要高,其執(zhí)行速度也要快出不少,所以可以根據(jù)需要把實(shí)時(shí)性能要求較高的程序復(fù)制到RAM中運(yùn)行,具體的方法和實(shí)例可以參考http://www.ti.com/general/docs/litabsmultiplefilelist.tsp?literatureNumber=spra958l下面的《Running an Application from Internal Flash Memory on the TMS320F28xxx 》。

            3) 評估代碼和數(shù)據(jù)的存儲地址的劃分,并根據(jù)需要修改鏈接文件

            i. 如果某段代碼和它所讀取的數(shù)據(jù)位于同一個(gè)物理內(nèi)存區(qū)間中,則因?yàn)樗鼈兪褂孟嗤牡刂房偩€等資源,無法同時(shí)訪問,造成了資源的沖突,這會降低程序的性能,所以最好把代碼和數(shù)據(jù)保存在不同的內(nèi)存區(qū)間中。

            ii. 等待狀態(tài)(wait)會降低系統(tǒng)性能,因?yàn)镃PU會執(zhí)行過多的無用狀態(tài)且在此期間無法處理別的任務(wù):當(dāng)CPU讀取或者訪問存儲單元或者外設(shè)的時(shí)候,該存儲器或者外設(shè)有可能在CPU默認(rèn)分配的時(shí)間內(nèi)無法完成數(shù)據(jù)的傳輸,此時(shí)就需要在CPU的ready信號中插入等待狀態(tài),直到數(shù)據(jù)傳輸完成才能讓CPU繼續(xù)執(zhí)行別的任務(wù)。C28x器件上,大部分的SARAM都是零等待的,但是在C2833x器件中,有一些模塊卻不是,例如某些Flash/OTP的訪問等。

            iii. 如果在代碼中大量使用兩個(gè)數(shù)據(jù)緩沖區(qū),則把兩個(gè)數(shù)據(jù)緩沖區(qū)存放在不同的RAM模塊中有可能會提高代碼的性能,因?yàn)榇罅孔x寫同一塊RAM區(qū)間會產(chǎn)生更多的流水線停滯,造成性能的降低。

            4) 使用編譯器中的統(tǒng)一內(nèi)存模式--unified_memory

            此模式把所有的存儲空間定義為一個(gè)整體,這樣編譯器在編譯時(shí)就可以使用RPT與PREAD指令來處理大部分的內(nèi)存復(fù)制調(diào)用和結(jié)構(gòu)體的分配。

            5) 使用Flash和外部存儲器

            如果代碼需要在Flash或外部存儲器中運(yùn)行,則在編譯時(shí)開啟-me選項(xiàng)。它將禁止編譯器使用快速分支指令(SBF/BF),轉(zhuǎn)而使用普通的跳轉(zhuǎn)指令(SB/B)。BF指令在默認(rèn)情況下是被啟用的,它能夠?qū)⑻D(zhuǎn)分支使用的指令周期從7個(gè)降低到4個(gè),在零等待狀態(tài)的SAM中執(zhí)行時(shí),快速分支指令的預(yù)讀特性使得它較為高效,但是在非零等待的存儲器中執(zhí)行時(shí),SBF/BF的預(yù)讀反而造成了性能的下降,此時(shí)需要人為地對預(yù)讀和等待進(jìn)行規(guī)劃。

            6) 使用內(nèi)聯(lián)函數(shù)

            在編譯時(shí)開啟內(nèi)聯(lián)函數(shù)功能,則編譯器會自動(dòng)把多次調(diào)用的函數(shù)進(jìn)行內(nèi)聯(lián),大大減少函數(shù)調(diào)用和返回操作所帶來的開銷。當(dāng)然,根據(jù)“空間換時(shí)間”的原則,開啟內(nèi)聯(lián)會增加一定的代碼尺寸。

            23. 為什么一個(gè)char類型的數(shù)組中,每個(gè)元素都占用了16bit的地址?

            這是因?yàn)樵贑28x上,字節(jié)(byte)和字(word)是等價(jià)的:也就是說它們都是16位或者說16比特(bit)寬的,即sizeof(int) == sizeof(char) == 1。

            24. sizeof(int) == sizeof(char) == 1貌似與ANSI標(biāo)準(zhǔn)是相違背的?

            在ANSI/ISO的C定義中,sizeof操作符以字節(jié)形式給出了其操作數(shù)的存儲大小。ANSI/ISO還規(guī)定,sizeof操作符取char的值時(shí),返回值為1。因?yàn)門MS320C28x中的字節(jié)是16位的,char也是16位的,所以sizeof的結(jié)果符合ANSI標(biāo)準(zhǔn)的。

            作為補(bǔ)充,選16位,而不是8位或者別的什么位數(shù)作為char的寬度,主要是為了統(tǒng)一尋址的便利,雖然在某種程度上說這增加了一定的存儲器空間占用,或者說浪費(fèi)了一些空間,因?yàn)樗鼈冊诖鎯臻g中制造了一些空洞。

            25. 如果char是16位的,那么如何高效地訪問8位的值?

            可以使用__byte()和__mov_byte()這樣的編譯器內(nèi)聯(lián)函數(shù)。請參考http://www.ex-cimer.com/article/265102.htm。

            26. 編譯結(jié)果提示undefined symbols,名字中包含$符號,怎么破?

            名字中帶美元符號的函數(shù),例如FS$$MPY, FS$$TOL等,都是RTS庫里的內(nèi)置函數(shù),編譯器提示我們這些函數(shù)未定義,表明我們沒有把對應(yīng)的RTS庫給加入到工程中,例如MPY是數(shù)學(xué)函數(shù),需要添加相關(guān)的數(shù)學(xué)庫,例如FPU數(shù)學(xué)庫等。

            27. 鏈接器提示“_c_int00 is not defined”,怎么破?

            在http://www.ex-cimer.com/article/262926.htm這篇文章中,已經(jīng)分析了_c_int00的含義。找不到_c_int00的話,說明我們遺漏了包含它的RTS庫,例如 rts2800_ml.lib、rts2800_fpu32.lib等待,這些RTS庫的具體區(qū)別在答疑解惑的第15條中已經(jīng)有對比了(http://www.ex-cimer.com/article/265108.htm)。

            28. 新版本的編譯器中,printf()/sprintf()函數(shù)貌似要使用更多的棧?

            這是因?yàn)閜rintf()函數(shù)被重新修改了,以支持多個(gè)級別的printf格式說明符支持和修正,以減少代碼大小和總內(nèi)存大小(包括bss)。printf由sprintf()間接調(diào)用,它使用一個(gè)400個(gè)元素的大小的局部數(shù)組。為了保存一致性,printf()一直都在使用這么大的內(nèi)存空間,而編譯器也在盡量避免使用malloc()進(jìn)行內(nèi)存分配。與老版本所不同的的是,此數(shù)組以前是靜態(tài)的,而現(xiàn)在它被保存在.bss,而不是棧中;這樣做的目的是,如果用戶使用C I/O,則他們往往會在使用合適尺寸的棧的同時(shí)盡量減小.bss的使用。

          c++相關(guān)文章:c++教程




          關(guān)鍵詞: DSP C/C++ Flash

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();