DSP編程技巧之15-使用代碼優化時必須考慮的五大問題

2021-01-17 電子產品世界

  前面我們提到了使用編譯器的優化選項進行不同級別的代碼優化的方法(請參考http://www.eepw.com.cn/article/203169.htm)。俗話說「好馬配好鞍」,即使我們有了強大的代碼優化工具,使得我們書寫的符合ANSI/ISO C/C++的代碼能被高效執行,我們在寫代碼時也要考慮到一些必要的原則,從而既能實現代碼的優化,也能保證代碼的安全,使得優化操作不會讓我們的代碼產生預期之外的結果。下面我們就來看一下在使用代碼優化時,必須考慮的五大問題。

本文引用地址:http://www.eepw.com.cn/article/255842.htm

  1. 小心使用彙編表達式

  在C/C++代碼中,有時候一些操作難免會對某些CPU寄存器進行操作,此時要使用內嵌的彙編表達式,例如asm("EALLOW"),或者重置某個中斷的掩碼寄存器等。在優化代碼時,編譯器會重新調整某些代碼段的順序,自己決定使用某些寄存器(例如AR0-AR7這樣的輔助寄存器),甚至刪除某些編譯器認為無用的變量、函數等,但是編譯器一般情況下並不會對內嵌的彙編代碼進行任何優化(除非這段彙編代碼被編譯器認為是永遠不會執行到的無用代碼),這就造成了編譯器的優化效果在這段彙編代碼和它的上下文代碼中無法進行有效的優化,特別是彙編代碼和C/C++代碼直接存在變量調用的情況下。所以非必要的情況下,要儘量避免C/C++和彙編語句的混用,如果確實需要的,也要在編譯之後檢查生成的彙編代碼是不是保證了我們代碼原意的完整性。

  2. 為必要的內存存取使用volatile關鍵字

  在C/C++代碼的編譯過程中,編譯器會分析數據流,從而儘量避免對存儲空間的直接存取。但是如果我們要在C/C++代碼中直接對內存地址進行操作的話,需要使用volatile關鍵字來定義變量,編譯器在優化時不會對volatile類型的變量進行優化。

  例如,在下面的代碼中,循環的結束條件為指針指向的地址為0xFF:

  unsigned int *ctrl;

  while (*ctrl !=0xFF);

  因為*ctrl是一個不變的表達式,這個循環會被優化為一次內存讀取。為了正確實現我們的代碼意圖,需要把ctrl定義為volatile類型:

  volatile unsigned int *ctrl

  使用volatile類型定義的類型在調試的時候還有一個極大的優勢,就是我們可以直接在CCS的debug窗口裡改變變量的值,極大地方便我們的調試。

  3. 小心使用Alias變量

  Alias(別名)在一個變量可以被至少兩種方式存取的時候會用到,例如,當兩個指針指向同一塊區域或對象時,我們稱一個指針 alias 另一個指針。Alias變量的使用要非常謹慎,因為會涉及到非直接的引用,從而破壞了優化效果。編譯器在優化時會分析代碼來決定在哪些地方會產生alias引用,然後在保持代碼正確性的基礎上「保守」地優化代碼。

  一般情況下,編譯器會假設,如果一個本地變量的地址被傳遞給某個函數,則這個函數有可能會通過指針操作改變這個本地變量的內容,但是這個函數不能在該地址被返回後仍然可以被別的指針操作所示使用,例如把這個本地變量的地址分配給一個全局變量或者返回它。如果這種假設被打破,則需要在編譯器選項裡使用-ma強制編譯器按照最壞情況的別名引用來進行一定的優化,在這種情況下,任何非直接的引用(例如使用指針)都可以引用到這個變量。

  4. 何時使用--aliased_variables選項?

  編譯器在優化時會假設,任何變量的地址在作為參數被傳遞給某個函數時,都不會在調用它的函數裡被任何Alias變量修改,例如:從函數返回地址,或者把地址分配給某個全局變量。但是如果我們使用管理類似下面操作的代碼的時候,就需要使用--aliased_variables選項來優化代碼:

  int *glob_ptr;

  g()

  {

  int x = 1;

  int *p = f(&x);

  *p = 5; /* p是x的別名 */

  *glob_ptr = 10; /* glob_ptr 也是 x的別名 */

  h(x);

  }

  int *f(int *arg)

  {

  glob_ptr = arg;

  return arg;

  }

  5. 含有FPU的器件:使用restrict關鍵詞來表明指針沒有被別名操作

  在含有FPU浮點協處理器的器件中,當使用--opt_level=2(優化寄存器、局部變量和全局變量的使用)的優化級別時,優化器會分析代碼的依賴性。為了更好地幫助優化器完成內存的依賴關係,我們可以把指針、引用或者數組等的聲明中加入restrict關鍵詞。restrict關鍵詞是C99標準引入的,它會通知編譯器,所有修改該指針所指向內存中內容的操作都必須通過該指針來修改,而不能通過其它途徑(其它變量或指針)來修改。使用這一原則能幫助編譯器優化某些代碼段,因為別名信息可以被更加快速地確認。使用restrict關鍵詞後因為可以執行更多的FPU操作,而FPU操作與CPU是並行的,所以帶來的優化效果是提高了性能和減小了代碼尺寸。

  我們可以使用下面例子中的代碼來告訴編譯器,a和b永遠不會在函數foo中指向同一個地址,並且a和b的內存地址也不會互相覆蓋(說明它們沒有依賴性,可以並行執行)。

  void foo(float * restrict a, float * restrict b)

  {

  /* foo's code here */

  }

  或者

  void foo(float c[restrict], float d[restrict])

  {

  /* foo's code here */

  }

c++相關文章:c++教程


相關焦點

  • 各大網站力推Java代碼優化:77案例+28技巧
    然而Java體系龐大、技術精深,如何寫出優質代碼,如何設計與優化系統架構,是高級開發者必須掌握的核心技術之一。一款軟體的最終體現就是代碼,而作為軟體架構師,如果沒有代碼優化的意識與技術,就不能稱之為軟體架構師。任何合格的軟體架構師,必須對代碼優化的概念與技術爛熟於胸,信手拈來。一個連代碼質量都不能控制好的架構師所設計的架構是不會有人信任的。
  • 網站編程錦上添花 分享8個常用代碼優化小助手
    企業建立網站,程式語言是人和計算機之間最直接的交流。而代碼又是編程的主要途徑。代碼優化是通過對程序代碼進行等價變化,而不改變程序的運行結果。常用的代碼優化技術有刪除多餘運算,循環不變代碼外提,強度削弱等。下面,IDC評述網與大家分享8個代碼優化小助手,供參考。1.
  • iCoding愛編程培養孩子五大思維能力
    而思維能力強的孩子,在遇到問題時,就能夠對腦海中存儲的信息進行靈活運用,並且有條理地表達出來。當孩子長大成人後進入職場,這種能力帶來的優勢會更加明顯,很容易遠超別人一大截。那麼,該如何培養孩子的思維能力,讓孩子真正受益一生呢?蘋果公司創始人賈伯斯早已對這個問題給出答案:「學編程最大的好處其實是可以對人的思維方式進行訓練。它是一個對思維完整性和邏輯性進行訓練的過程。」
  • 「原創」Java並發編程系列02|並發編程三大核心問題
    要快速準確的發現並解決這些問題,首先就是要弄清並發編程的本質,並發編程要解決的是什麼問題。本文將帶你深入理解並發編程要解決的三大問題:原子性、可見性、有序性。補充知識硬體的發展中,一直存在一個矛盾,CPU、內存、I/O設備的速度差異。
  • Java代碼的優化方法有哪些
    說到代碼優化,每個人或多或少都掌握一到兩種方法,但是這樣的方法對提升代碼運行效率效果不大,最重要是對代碼的重視和了解,這樣才能提升代碼的運行效率。在進行代碼優化的過程中,方法是非常重要的,多掌握幾種方法,根據代碼的不同情況選擇適合的方法進行優化。
  • word使用技巧5(宏與VBA編程)
    野貓教學視頻第10期,本期視頻內容提要:1)域代碼;2)宏與VBA編程;3)新建功能區的選項卡;4)新建快速訪問工具。常見辦公問題:1、如何一鍵修改Word中100張圖片或表格的寬度、並使之居中?(合併字符、雙行合一、制表符)6、你知道腳註、尾注、題注和VBA的使用方法嗎?7、如何給PPT製作捲軸動畫?(動畫)8、如何一鍵切換PPT的風格?(模板或主題)9、如何讓PPT頁腳的總頁碼自動不計前2頁封面?(域代碼)10、如何利用Excel實現手機號歸屬地自動查詢?
  • 「技巧」企業網站優化必須學會H標籤的使用技巧
    網站優化中H標籤作用為修飾網頁標題內容的存在,引導搜尋引擎判定網頁核心,能夠有效的引導和促進抓取和識別,降低搜尋引擎誤判,從而正確的促進SEO優化排名,H標籤的系列當中:H1-H6文字由大至小,重要與權重程度亦依次遞減。無論是框架布局、還是站內文章優化,對H標籤的使用,都是比較講究的,當然H標籤的操作不當,容易造成網站過度優化,導致百度降權。
  • 無代碼BPM平臺的使用和推薦
    但更主要的,BPM是一個應用系統化流程重新設計和使用自動化工具來提高特定、可重複的業務流程的系統。但是,如果不懂得編程(代碼),使用早期的BPM簡直是難如登天。想要優化業務流程的公司需要花費大量的錢不斷的讓外包公司「二次開發」,或者花費大量時間去等待自己的IT團隊研發出匹配業務的系統。直到無代碼的BPM到來才打破僵局。
  • 敲代碼從小孩抓起,編程機器人是新世代的童年玩具?
    教授說:「儘管青少年學習編程是為了他們的職業發展做準備,但對於孩子來說,更重要的是幫助他們培養良好的思考方式和創造力。」Bers曾協助開發了適用於兒童的ScratchJr語言和在世界各地的教室中都可以找到的無屏幕編程機器人KIBO。她認為,編程應當是另一種讀寫能力,兒童在學習閱讀時就應該學習編程。
  • 如何編寫漂亮的 React 代碼?|javascript|程式語言|react|coffee...
    你很少會看到一個開發人員舉手在站例會上告訴他們的同事他們對代碼在屏幕上的樣子不滿意。我不確定是否有人會這麼做,但我的看法有所不同。  我是在從事一個副業項目時,開始考慮 React 的美觀問題的。作為大多數以編碼為職業和愛好的程式設計師,工作和休閒之間的區別是由你所享受到的快樂所決定的。
  • JAVA並發編程:並發問題的根源及主要解決方法
    比如在進行讀寫磁碟等耗時高的任務時,就可以將寶貴的CPU資源讓出來讓其他線程去獲取CPU並執行任務。但這樣的切換也會導致問題,那就是會破壞線程某些任務的原子性。比如java中簡單的一條語句count += 1。
  • 《代碼整潔之道》:5大基本要點
    全文共3257字,預計學習時長10分鐘評論區常常有小夥伴推薦羅伯特·C·馬丁的《代碼整潔之道(Clean Code)》。今天我們就來了解一下這本書,它值不值得一看?相反,在本書中馬丁呼籲發展強烈的個人原則感,且不斷說明將「髒代碼」變整潔所需的努力和職責。本書將其稱為「代碼感」,它要求「嚴格使用艱難獲得整潔代碼的大量小技巧。」「整潔代碼並非遵循一組規則編寫的。不可能因為學習一套金規玉律就成為軟體大師。專業精神和手工藝來自於推動規則形成的價值。」
  • 你適合學編程嗎?這五大必備特質你擁有幾點
    昨天聽到學員們在談論,學編程的好處,當然也聽到了一些學員說當初選擇當程式設計師有點草率,那麼今天就給大家普及一下我個人認為程式設計師的五大必備特質:學員:雖然python只學了皮毛,但我迫不及待地用了起來,因為急待解決的問題真是太多太多了。
  • 清華畢業生開發新特效程式語言:99 行代碼背後 20 多年的故事……
    技術向:99 行代碼的《冰雪奇緣》做CG 特效一直都是一個燒錢的事情,不然我們看動畫片時也不會總是刷「五毛特效」、「經費在燃燒」這些關鍵詞。背後的原因一是門檻高,二是對性能有著極高的要求。自己渲染過視頻的人都知道,隨便一個小視頻,哪怕是高配筆記本也要渲染半天。
  • 想學一門新的程式語言?考慮一下Go (Golang)吧
    Defer的使用直接明了。用于格式化字符串的fmt包好像解決了我之前未發現的問題。我開始認識到Go作為新興程式語言近年來得到快速發展的原因。因此,我決定更深入地研究Go語言的初衷,以確定它是否值得花時間學習。
  • 清華畢業生開發新特效程式語言,99行代碼實現《冰雪奇緣》
    安裝它就像TensorFlow一樣容易,使用起來也是差不多:import taichi as ti甚至,Taichi的發明者胡淵鳴同學還為此編寫了完整使用教程。Taichi中的可微分編程,可以通過蠻力的梯度下降有效地優化神經網絡控制器,而不必使用強化學習。10種可微分模擬器中的大多數模型可以在2-3小時內實現,而且大部分不需要GPU。這些示例中,彈性體、剛體、流體、光線的折射、彈性碰撞,常見物理環境應有盡有。
  • 機器編程要讓全球78億人都能寫代碼
    不過,機器編程想讓另外99%的人也能編寫代碼。這聽起來很科幻,但英特爾在機器編程領域的進展讓我們相信讓100%的人都能寫代碼並非觸不可及。為什麼全員都能編程後程式設計師不會失業?什麼是機器編程?機器編程並非近來提出的全新概念,在20世紀50年代時它被稱為「程序合成」,程序合成是一種使用數學證明的非常形式化的方法,它採用某種形式的輸入,然後生成一個軟體。
  • AEA人工智慧可視化編程及代碼教育解決方案:打開算法黑箱
    2020年6月,國內領先人工智慧教育技術提供商聯合偉世發布了新一代「人工智慧可視化編程及代碼教育套件」——AEA600系列。相比於傳統的人工智慧可視化編程平臺,如:Scratch、Mixly來說,AEA600教育套件採用了軟硬體相結合的方式,對Mixly編程平臺進行性能優化,大幅度提升了其AI部分的功能,並精心製作了適合人工智慧教育的30個實驗案例,覆蓋語音、手寫數字、口罩可完成數據採集、訓練、推理的人工智慧全過程,全方位地滿足學生學習人工智慧的需求。
  • 為什麼要讓你的代碼儘可能簡單
    你是否想成為一位寫「不良代碼」的「不良程式設計師」,因為你讀過有關編寫「不完美的初稿」的建議?不,你想成為一名「成功的程式設計師」,編寫「出色的代碼」,因為你正在遵循從「簡單的初稿」開始編碼的技巧。如果你曾經複製過一個代碼示例,然後對其進行了調整以供自己使用,那麼實際上你已經學會了「簡單的初稿」的訣竅。
  • 清華姚班畢業生開發新特效程式語言,99行代碼實現《冰雪奇緣》
    安裝它就像TensorFlow一樣容易,使用起來也是差不多:importtaichiasti甚至,Taichi的發明者胡淵鳴同學還為此編寫了完整使用教程。Taichi中的可微分編程,可以通過蠻力的梯度下降有效地優化神經網絡控制器,而不必使用強化學習。10種可微分模擬器中的大多數模型可以在2-3小時內實現,而且大部分不需要GPU。這些示例中,彈性體、剛體、流體、光線的折射、彈性碰撞,常見物理環境應有盡有。