<var id="fnfpo"><source id="fnfpo"></source></var>
<rp id="fnfpo"></rp>

<em id="fnfpo"><object id="fnfpo"><input id="fnfpo"></input></object></em>
<em id="fnfpo"><acronym id="fnfpo"></acronym></em>
  • <th id="fnfpo"><track id="fnfpo"></track></th>
  • <progress id="fnfpo"><track id="fnfpo"></track></progress>
  • <tbody id="fnfpo"><pre id="fnfpo"></pre></tbody>

  • x
    x

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

    發布時間:2014-12-15 11:52    發布者:看門狗
    關鍵詞: DSP編程
    作者:paradoxfx 來源:電子產品世界

    22. 除了使用編譯器的優化選項之外,還可以使用什么方法提高程序的性能?

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

      1) 代碼運行在Flash中

      一定要使能預讀緩沖區,并配置適當的等待狀態。一般在各個器件的頭文件與外設示例包里都有對應的例子。

      2) 把時間關鍵的代碼和/常數數組等從Flash復制到RAM中運行

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

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

      i. 如果某段代碼和它所讀取的數據位于同一個物理內存區間中,則因為它們使用相同的地址總線等資源,無法同時訪問,造成了資源的沖突,這會降低程序的性能,所以最好把代碼和數據保存在不同的內存區間中。

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

      iii. 如果在代碼中大量使用兩個數據緩沖區,則把兩個數據緩沖區存放在不同的RAM模塊中有可能會提高代碼的性能,因為大量讀寫同一塊RAM區間會產生更多的流水線停滯,造成性能的降低。

      4) 使用編譯器中的統一內存模式--unified_memory

      此模式把所有的存儲空間定義為一個整體,這樣編譯器在編譯時就可以使用RPT與PREAD指令來處理大部分的內存復制調用和結構體的分配。

      5) 使用Flash和外部存儲器

      如果代碼需要在Flash或外部存儲器中運行,則在編譯時開啟-me選項。它將禁止編譯器使用快速分支指令(SBF/BF),轉而使用普通的跳轉指令(SB/B)。BF指令在默認情況下是被啟用的,它能夠將跳轉分支使用的指令周期從7個降低到4個,在零等待狀態的SAM中執行時,快速分支指令的預讀特性使得它較為高效,但是在非零等待的存儲器中執行時,SBF/BF的預讀反而造成了性能的下降,此時需要人為地對預讀和等待進行規劃。

      6) 使用內聯函數

      在編譯時開啟內聯函數功能,則編譯器會自動把多次調用的函數進行內聯,大大減少函數調用和返回操作所帶來的開銷。當然,根據“空間換時間”的原則,開啟內聯會增加一定的代碼尺寸。

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

      這是因為在C28x上,字節(byte)和字(word)是等價的:也就是說它們都是16位或者說16比特(bit)寬的,即sizeof(int) == sizeof(char) == 1。

      24. sizeof(int) == sizeof(char) == 1貌似與ANSI標準是相違背的?

      在ANSI/ISO的C定義中,sizeof操作符以字節形式給出了其操作數的存儲大小。ANSI/ISO還規定,sizeof操作符取char的值時,返回值為1。因為TMS320C28x中的字節是16位的,char也是16位的,所以sizeof的結果符合ANSI標準的。

      作為補充,選16位,而不是8位或者別的什么位數作為char的寬度,主要是為了統一尋址的便利,雖然在某種程度上說這增加了一定的存儲器空間占用,或者說浪費了一些空間,因為它們在存儲空間中制造了一些空洞。

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

      可以使用__byte()和__mov_byte()這樣的編譯器內聯函數。

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

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

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

      已經分析過了_c_int00的含義。找不到_c_int00的話,說明我們遺漏了包含它的RTS庫,例如 rts2800_ml.lib、rts2800_fpu32.lib等待,這些RTS庫的具體區別在答疑解惑的第15條中已經有對比了。

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

      這是因為printf()函數被重新修改了,以支持多個級別的printf格式說明符支持和修正,以減少代碼大小和總內存大小(包括bss)。printf由sprintf()間接調用,它使用一個400個元素的大小的局部數組。為了保存一致性,printf()一直都在使用這么大的內存空間,而編譯器也在盡量避免使用malloc()進行內存分配。與老版本所不同的的是,此數組以前是靜態的,而現在它被保存在.bss,而不是棧中;這樣做的目的是,如果用戶使用C I/O,則他們往往會在使用合適尺寸的棧的同時盡量減小.bss的使用。
    本文地址:http://www.portaltwn.com/thread-135072-1-1.html     【打印本頁】

    本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
    您需要登錄后才可以發表評論 登錄 | 立即注冊

    廠商推薦

    • Microchip視頻專區
    • EtherCAT®和Microchip LAN925x從站控制器介紹培訓教程
    • MPLAB®模擬設計器——在線電源解決方案,加速設計
    • 讓您的模擬設計靈感,化為觸手可及的現實
    • 深度體驗Microchip自動輔助駕駛應用方案——2025巡展開啟報名!
    • 貿澤電子(Mouser)專區
    關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
    電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
    快速回復 返回頂部 返回列表
    精品一区二区三区自拍图片区_国产成人亚洲精品_亚洲Va欧美va国产综合888_久久亚洲国产精品五月天婷