0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

深入淺出編譯優(yōu)化選項(xiàng)(上)

IAR愛(ài)亞系統(tǒng) ? 來(lái)源:IAR愛(ài)亞系統(tǒng) ? 2023-04-14 09:11 ? 次閱讀

在前文《如何為嵌入式軟件開(kāi)發(fā)選擇編譯器》中講到編譯器對(duì)于嵌入式軟件開(kāi)發(fā)的重要性,以及如何選擇一款優(yōu)秀的編譯器。 文中也比較了現(xiàn)有主流編譯器的編譯優(yōu)化性能,IAR Embedded Workbench編譯器不論在輸出代碼體積還是性能均處于業(yè)界領(lǐng)先地位。

本文中,我們將以IAR Embedded Workbench編譯器為例,闡述如何配置編譯優(yōu)化選項(xiàng),以達(dá)到嵌入式軟件代碼性能和體積的最佳平衡。由于篇幅關(guān)系,本主題將會(huì)分成上、下兩篇。

編譯器代碼構(gòu)建過(guò)程

在介紹如何配置編譯器優(yōu)化選項(xiàng)之前,讓我們先來(lái)了解下編譯器構(gòu)建的過(guò)程。 以IAR Embedded Workbench編譯器為例,其代碼構(gòu)建過(guò)程如下圖。

wKgaomQ4qHiATtY9AAK3SC0c5F4420.png

構(gòu)建過(guò)程分為兩部分:前端和后端。

前端主要將C代碼通過(guò)解析器(Parser)生產(chǎn)中間代碼(Intermediate Code),在這個(gè)過(guò)程中會(huì)介入優(yōu)化器(High-Level Optimizer),其優(yōu)化策略包括函數(shù)內(nèi)聯(lián)(Function in lining), 冗余代碼消除(Dead code elimination), 循環(huán)展開(kāi)(Loop unrolling)等。

后端則將中間代碼通過(guò)目標(biāo)代碼生成器(Code Generator)生成目標(biāo)匯編代碼(Target Code),在這個(gè)過(guò)程中也會(huì)介入優(yōu)化器(Low-Level Optimizer),其優(yōu)化策略包括調(diào)度(Scheduling), 窺視孔(Peephole), 函數(shù)調(diào)用優(yōu)化(Cross call)等。 然后由匯編器(Assembler)將匯編代碼轉(zhuǎn)換成目標(biāo)機(jī)器碼(Object Code)。 最后,通過(guò)鏈接器(Linker),將所有的目標(biāo)機(jī)器碼鏈接成elf格式的可執(zhí)行二進(jìn)制代碼文件。 在鏈接階段也有相應(yīng)的優(yōu)化器(Linker time optimization)進(jìn)行優(yōu)化。

IAR Embedded Workbench
編譯優(yōu)化選項(xiàng)介紹

在IAR Embedded Workbench(基于EWARM v9.32.2)中通過(guò)菜單欄(Project -> Options)打開(kāi)項(xiàng)目選項(xiàng)界面,選中“C/C++ Compiler”欄目,并且在右邊選項(xiàng)卡選中“Optimizations”,即可進(jìn)行編譯優(yōu)化選項(xiàng)配置,如下圖所示。

wKgZomQ4qHiAIV8WAALyRNso2P0562.png

1. 編譯優(yōu)化等級(jí)配置

如下圖所示,IAR Embedded Workbench共分為4個(gè)優(yōu)化等級(jí)(None, Low, Medium, High),其中等級(jí)“High”又分為3個(gè)子優(yōu)化等級(jí)(Balanced, Size, Speed)。 下表是各個(gè)優(yōu)化等級(jí)對(duì)應(yīng)的優(yōu)化策略總覽。

? 選擇“None”,編譯器只會(huì)進(jìn)行無(wú)用代碼消除等基本優(yōu)化,但編譯速度快,并且最適合C/C++源代碼調(diào)試。

? 最高優(yōu)化等級(jí)除了High(Balanced)之外,也可以選擇High(Size)對(duì)于代碼體積進(jìn)行極致優(yōu)化; 或者選擇High(Speed) ,并且勾選 No size constraints,則對(duì)于代碼性能進(jìn)行極致優(yōu)化。

關(guān)于編譯優(yōu)化微調(diào)項(xiàng)(Enabled transformations)配置方法,我們將在《深入淺出編譯優(yōu)化選項(xiàng)(下)》詳細(xì)介紹,敬請(qǐng)關(guān)注。

wKgaomQ4qHiABThRAAFS4kcJ1Xc036.png

2. 多文件編譯(Multi-file Compilation)

通常情況下,編譯器逐個(gè)編譯C/C++源文件。 編譯器的單次編譯視野僅限于當(dāng)前C/C++源文件,不能獲知其他源文件的情況,包括全局變量,函數(shù)調(diào)用,指針別名等關(guān)系。 因此編譯器會(huì)采用較為保守和安全的優(yōu)化假設(shè)。

IAR Embedded Workbench則為用戶提供了 **“多文件編譯” **功能,如下圖。 編譯器在工程全局級(jí)別或者文件組級(jí)別,允許一次編譯多個(gè)文件,從而增加了編譯視野,可以進(jìn)行更為深度的編譯優(yōu)化策略實(shí)施,通常能獲得更好的編譯優(yōu)化效果。

wKgaomQ4qHiAONnrAAHY7jAN5pw237.png

3. 靈活配置編譯優(yōu)化選項(xiàng)作用域

IAR Embedded Workbench提供了不同作用域的編譯優(yōu)化選項(xiàng)設(shè)置,使用戶能夠更加靈活的進(jìn)行配置,對(duì)不同編譯優(yōu)化需求的代碼進(jìn)行分別配置。

? 全局設(shè)置:如之前介紹的編譯優(yōu)化選項(xiàng)設(shè)置方法均為全局設(shè)置,作用于整個(gè)工程范圍。

? 每個(gè)文件/每個(gè)組的設(shè)置:當(dāng)文件/組中的所有函數(shù)必須具有與項(xiàng)目不同的編譯優(yōu)化設(shè)置時(shí),打開(kāi)文件/組編譯選項(xiàng)界面(在項(xiàng)目管理器選中文件/組,右擊鼠標(biāo)選擇Options),選擇“Override inherited settings”,如下圖。 然后進(jìn)行編譯優(yōu)化設(shè)置。

wKgZomQ4qHiAQS74AAK6vMOJFQg394.png

wKgZomQ4qHiAM3EFAAJF_US3enM720.png

? 單個(gè)函數(shù):當(dāng)某些函數(shù)必須具有不同的編譯優(yōu)化設(shè)置時(shí),可以在源代碼中使用 #pragma 關(guān)鍵字進(jìn)行單獨(dú)配置,如下例。

wKgaomQ4qHiAbelBAACy2EacdaM714.png

4. 鏈接階段優(yōu)化選項(xiàng)

IAR Embedded Workbench在鏈接階段也提供了相應(yīng)的代碼優(yōu)化選項(xiàng),如下圖。

? 鏈接階段默認(rèn)消除未使用的變量和函數(shù)。

? 小函數(shù)內(nèi)聯(lián)(inline small routines):將對(duì)小函數(shù)的某些調(diào)用替換為函數(shù)的本體。

? 合并重復(fù)段(Merge duplicate sections):鏈接器可以檢測(cè)具有相同內(nèi)容的只讀段,并僅保留每個(gè)此類段的一個(gè)副本,從而將對(duì)任何重復(fù)段的所有引用重定向到保留的段。

? C++虛擬函數(shù)消除(Perform C++ virtual function elimination):虛函數(shù)是 C++ 中的一種特殊函數(shù),它的實(shí)際調(diào)用取決于對(duì)象的實(shí)際類型。 虛函數(shù)的調(diào)用需要運(yùn)行時(shí)動(dòng)態(tài)解析,因此會(huì)導(dǎo)致一定的運(yùn)行時(shí)開(kāi)銷。 “C++虛擬函數(shù)消除” 可刪除不需要的虛擬函數(shù)和動(dòng)態(tài)運(yùn)行時(shí)類型信息,以減少程序運(yùn)行時(shí)的開(kāi)銷,提高程序的性能。

wKgZomQ4qHiAEp0JAAJ-Y60a61Q269.png

嵌入式軟件編譯優(yōu)化選項(xiàng)配置整體思路

嵌入式系統(tǒng)中通常硬件資源有限,特別是存儲(chǔ)器容量,直接與MCU硬件成本掛鉤,影響整個(gè)系統(tǒng)的硬件物料成本; 另一方面,嵌入式軟件又需要對(duì)外部信號(hào)進(jìn)行實(shí)時(shí)響應(yīng),對(duì)外部設(shè)備進(jìn)行實(shí)時(shí)控制,比如馬達(dá)控制組件; 除此之外,電池供電的嵌入式設(shè)備需要具備低功耗特性,要求CPU盡可能處于深度睡眠狀態(tài),以盡可能延長(zhǎng)設(shè)備的單次電池工作時(shí)間。 結(jié)合上述情況,對(duì)于嵌入式軟件進(jìn)行編譯優(yōu)化選項(xiàng)配置需要進(jìn)行差異化考量,具體如下:

? 對(duì)于整個(gè)嵌入式軟件項(xiàng)目作用域,可以考慮極致代碼體積優(yōu)化。 較少的代碼體積可以適配較小flash容量的MCU,從而節(jié)省硬件物料成本。

? 對(duì)于運(yùn)行頻度很高的代碼段,可以考慮極致代碼性能優(yōu)化。 這樣可以使得關(guān)鍵代碼在相同CPU速度的情況下,達(dá)到更高的實(shí)時(shí)響應(yīng)速度。

? 另外,在電池供電的低功耗應(yīng)用中,CPU一般處在深度睡眠狀態(tài)。 通常是間隔一段時(shí)間或者外部事件到來(lái),喚醒CPU執(zhí)行一個(gè)任務(wù),然后CPU重新回到深度睡眠狀態(tài)。 設(shè)備功耗等于CPU深度睡眠的靜態(tài)功耗和任務(wù)運(yùn)行的動(dòng)態(tài)功耗之和。 根據(jù)MCU硬件電氣特性,其單位時(shí)間動(dòng)態(tài)功耗(mA級(jí)別)要遠(yuǎn)大于單位時(shí)間靜態(tài)功耗(uA級(jí)別)。

對(duì)于經(jīng)常需要喚醒執(zhí)行的軟件任務(wù),可以考慮極致代碼性能優(yōu)化。 這樣會(huì)減少動(dòng)態(tài)功耗的時(shí)間,以達(dá)到整體功耗的下降,從而增加設(shè)備的電池使用壽命。

注意事項(xiàng):

? #pragma optimize 只能降低對(duì)應(yīng)函數(shù)的優(yōu)化等級(jí),或者選擇另外一種優(yōu)化策略。 如果 pragma optimize的優(yōu)化等級(jí)比編譯器選項(xiàng)的優(yōu)化等級(jí)高,那么 pragma optimize命令會(huì)被忽略。

? 高優(yōu)化等級(jí)會(huì)讓編譯時(shí)間變長(zhǎng),同時(shí)讓調(diào)試變得困難一些(因?yàn)楦邇?yōu)化等級(jí)會(huì)讓生成的代碼和源代碼的對(duì)應(yīng)關(guān)系沒(méi)有那么直接)。 如果在調(diào)試過(guò)程中發(fā)現(xiàn)類似的問(wèn)題,建議降低優(yōu)化等級(jí)進(jìn)行調(diào)試。

總結(jié)

IAR Embedded Workbench是一款業(yè)界領(lǐng)先的編譯工具鏈,除了提供卓越的性能之外,還提供了豐富靈活的編譯優(yōu)化選項(xiàng)配置,以幫助用戶在不同的嵌入式應(yīng)用需求下,都能找到最佳的嵌入式軟件代碼性能和體積的平衡點(diǎn)。

在下一篇《深入淺出編譯優(yōu)化選項(xiàng)(下)》中,我們將介紹編譯過(guò)程中的優(yōu)化策略以及如何在IAR Embedded Workbench配置編譯優(yōu)化微調(diào)項(xiàng)(Enabled transformations),讓用戶可以根據(jù)代碼需求配置出更加精準(zhǔn)的編譯優(yōu)化策略組合。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5082

    文章

    19126

    瀏覽量

    305197
  • IAR
    IAR
    +關(guān)注

    關(guān)注

    5

    文章

    352

    瀏覽量

    36681
  • 優(yōu)化
    +關(guān)注

    關(guān)注

    0

    文章

    220

    瀏覽量

    23906
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4788

    瀏覽量

    68612
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1634

    瀏覽量

    49132

原文標(biāo)題:深入淺出編譯優(yōu)化選項(xiàng)(上)

文章出處:【微信號(hào):IAR愛(ài)亞系統(tǒng),微信公眾號(hào):IAR愛(ài)亞系統(tǒng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    深入淺出AVR

    深入淺出AVR,一本書(shū)。
    發(fā)表于 07-15 12:02

    深入淺出玩轉(zhuǎn)FPGA

    深入淺出玩轉(zhuǎn)FPGA
    發(fā)表于 07-21 09:21

    深入淺出ARM7

    深入淺出ARM7
    發(fā)表于 08-18 10:12

    HDMI技術(shù)深入淺出

    HDMI技術(shù)深入淺出
    發(fā)表于 08-19 10:52

    深入淺出Android

    深入淺出Android
    發(fā)表于 08-20 10:14

    深入淺出Android

    深入淺出Android
    發(fā)表于 04-26 10:48

    深入淺出安防視頻監(jiān)控系統(tǒng)

    深入淺出安防視頻監(jiān)控系統(tǒng)深入淺出安防視頻監(jiān)控系統(tǒng)
    發(fā)表于 05-22 19:28

    深入淺出AVR

    深入淺出AVR
    發(fā)表于 08-23 10:10

    NI 網(wǎng)絡(luò)講壇:深入淺出TDMS文件格式()--labvi

    NI 網(wǎng)絡(luò)講壇:深入淺出TDMS文件格式()--labview視頻教程
    發(fā)表于 03-26 16:48 ?107次下載

    深入淺出數(shù)據(jù)分析

    深入淺出數(shù)據(jù)分析,有需要的朋友下來(lái)看看。
    發(fā)表于 01-15 14:22 ?0次下載

    深入淺出談多層面板布線技巧

    深入淺出談多層面板布線技巧
    發(fā)表于 12-13 22:20 ?0次下載

    深入淺出Android—Android開(kāi)發(fā)經(jīng)典教材

    深入淺出Android—Android開(kāi)發(fā)經(jīng)典教材
    發(fā)表于 10-24 08:52 ?15次下載
    <b class='flag-5'>深入淺出</b>Android—Android開(kāi)發(fā)經(jīng)典教材

    深入淺出數(shù)字信號(hào)處理

    深入淺出數(shù)字信號(hào)處理
    發(fā)表于 12-07 20:14 ?538次閱讀

    深入淺出學(xué)習(xí)250個(gè)通信原理資源下載

    深入淺出學(xué)習(xí)250個(gè)通信原理資源下載
    發(fā)表于 04-12 09:16 ?28次下載

    深入淺出編譯優(yōu)化選項(xiàng)(下)

    在《深入淺出編譯優(yōu)化選項(xiàng))》中,我們介紹了如何在IAR Embedded Workbench編譯
    的頭像 發(fā)表于 04-21 10:19 ?1283次閱讀