當前位置:首頁 » 編程軟體 » 指令布局優化是編譯器優化嗎

指令布局優化是編譯器優化嗎

發布時間: 2023-05-09 12:27:29

1. 編譯器的組成及各部分的功能及作用

1. 詞法分析 詞法分析器根據詞法規則識別出源程序中的各個記號(token),每個記號代表一類單詞(lexeme)。源程序中常見的記號可以歸為幾大類:關鍵字、標識符、字面量和特殊符號。詞法分析器的輸入是源程序,輸出是識別的記號流。詞法分析器的任務是把源文件的字元流轉換成記號流。本質上它查看連續的字元然後把它們識別為「單詞」。 2. 語法分析 語法分析器根據語法規則識別出記號流中的結構(短語、句子),並構造一棵能夠正確反映該結構的語法樹。 3. 語義分析 語義分析器根據語義規則對語法樹中的語法單元進行靜態語義檢查,如果類型檢查和轉換等,其目的在於保證語法正確的結構在語義上也是合法的。 4. 中間代碼生成 中間代碼生成器根據語義分析器的輸出生成中間代碼。中間代碼可以有若干種形式,它們的共同特徵是與具體機器無關。最常用的一種中間代碼是三地址碼,它的一種實現方式是四元式。三地址碼的優點是便於閱讀、便於優化。 5. 中間代碼優化 優化是編譯器的一個重要組成部分,由於編譯器將源程序翻譯成中間代碼的工作是機械的、按固定模式進行的,因此,生成的中間代碼往往在時間和空間上有很大浪費。當需要生成高效目標代碼時,就必須進行優化。 6. 目標代碼生成 目標代碼生成是編譯器的最後一個階段。在生成目標代碼時要考慮以下幾個問題:計算機的系統結構、指令系統、寄存器的分配以及內存的組織等。編譯器生成的目標程序代碼可以有多種形式:匯編語言、可重定位二進制代碼、內存形式。 7 符號表管理 符號表的作用是記錄源程序中符號的必要信息,並加以合理組織,從而在編譯器的各個階段能對它們進行快速、准確的查找和操作。符號表中的某些內容甚至要保留到程序的運行階段。 8 出錯處理用戶編寫的源程序中往往會有一些錯誤,可分為靜態錯誤和動態錯誤兩類。所謂動態錯誤,是指源程序中的邏輯錯誤,它們發生在程序運行的時候,也被稱作動態語義錯誤,如變數取值為零時作為除數,數組元素引用時下標出界等。靜態錯誤又可分為語法錯誤和靜態語義錯誤。語法錯誤是指有關語言結構上的錯誤,如單詞拼寫錯、表達式中缺少操作數、begin和end不匹配等。靜態語義錯誤是指分析源程序時可以發現的語言意義上的錯誤,如加法的兩個操作數中一個是整型變數名,而另一個是數組名等。

2. 應用編譯優化有什麼用

應用編譯優化的作用是:提高運行能力因為程序優化前,有3個變數需要3個寄存器,一次乘法運算。程序優化後,只有1個變數需要一個寄存器,沒有乘法運算。

並且這個優化看起來很微不足道,但實際上用途很廣。為了程序的可讀性和可維護性,大多數程序員應該還是會選用第一種方式。

寫3行程序而不是直接甩下一行int ticks = 491520讓後來讀程序的人摸不到頭腦。有了編譯器的優化,程序員既可以寫出易讀的程序又不必擔心性能受影響。

尤其是在嵌入式領域,很多低端晶元根本就沒有硬體乘法器,如果程序不做上述優化可能這3行代碼需要幾十個cycle,優化過後一個cycle就搞定。

應用編譯優化的級別:

第一級:代碼調整。

代碼調整是一種局部的思維方式;基本上不觸及演算法層級;它面向的是代碼,而不是問題; 所以:語句調整,用匯編重寫、指令調整、換一種語言實現、換一個編譯器、循環展開、參數傳遞優化等都屬於這一級。

第二級:新的視角。

新的視角強調的重點是針對問題的演算法;即選擇和構造適合於問題的演算法。

第三級:表驅動狀態機。

將問題抽象為另一種等價的數學模型或假想機器模型,比如構造出某種表驅動狀態機;這一級其實是第二級的延伸,只是產生的效果更加明顯,但它有其本身的特點。

3. 電腦編程的基礎知識——編譯器和連接器


我從沒見過(不過應該有)任何一本C++教材有講過何謂編譯器(Compiler)及連接器(Linker)(倒是在很老的C教材中見過),現在都通過一個類似VC這樣的編程環境隱藏了大量東西,將這些封裝起來。在此,對它們的理解是非常重要的,本系列後面將大量運用到這兩個詞彙,其決定了能否理解如聲明、定義、外部變數、頭文件等非常重要的關鍵。
前面已經說明了電腦編程就是一個「翻譯」過程,要把用戶的程序翻譯成CPU指令,其實也就是機器代碼。所謂的機器代碼就是用CPU指令書寫的程序,被稱作低級語言。而程序員的工作就是編寫出機器代碼。由於機器代碼完全是一些數字組成(CPU感知的一切都是數字,即使是指令,也只是1代表加法、2代表減法這一類的數字和工作的映射),人要記住1是代表加法、2是代表減法將比較困難,並且還要記住第3塊內存中放的是圓周率,而第4塊內存中放的是有效位數。所以發明了匯編語言,用一些符號表示加法而不再用1了,如用ADD表示加法等。
由於使用了匯編語言,人更容易記住了,但是電腦無法理解(其只知道1是加頌隱法,不知道ADD是加法,因為電腦只能看見數字),所以必須有個東西將匯編代碼翻譯成機器代碼,也就是所謂的編譯器。即編譯器是將一種語言翻譯成另一種語言的程序。即使使用了匯編語言,但由於其幾乎只是將CPU指令中的數字映射成符號以幫助記憶而已,還是使用的空跡電腦的思考方式進行思考的,不夠接近人類的思考習慣,故而出現了紛繁復雜的各種電腦編程語言,如:PASCAL、BASIC、C等,其被稱作高級語言,因為比較接近人的思考模式(尤其C++的類的概念的推出),而匯編語言則被稱作低級語言(C曾被稱作高級的低級語言),因為它們不是很符合人類的思考模式,人類書野虧廳寫起來比較困難。由於CPU同樣不認識這些PASCAL、BASIC等語言定義的符號,所以也同樣必須有一個編譯器把這些語言編寫的代碼轉成機器代碼。對於這里將要講到的C++語言,則是C++語言編譯器(以後的編譯器均指C++語言編譯器)。
因此,這里所謂的編譯器就是將我們書寫的C++源代碼轉換成機器代碼。由於編譯器執行一個轉換過程,所以其可以對我們編寫的代碼進行一些優化,也就是說其相當於是一個CPU指令程序員,將我們提供的程序翻譯成機器代碼,不過它的工作要簡單一些了,因為從人類的思考方式轉成電腦的思考方式這一過程已經由程序員完成了,而編譯器只是進行翻譯罷了(最多進行一些優化)。
還有一種編譯器被稱作翻譯器(Translator),其和編譯器的區別就是其是動態的而編譯器是靜態的。如前面的BASIC的編譯器在早期版本就被稱為翻譯器,因為其是在運行時期即時進行翻譯工作的,而不像編譯器一次性將所有代碼翻成機器代碼。對於這里的「動態」、「靜態」和「運行時期」等名詞,不用刻意去理解它,隨著後續文章的閱讀就會了解了。
編譯器把編譯後(即翻譯好的)的代碼以一定格式(對於VC,就是COFF通用對象文件格式,擴展名為.obj)存放在文件中,然後再由連接器將編譯好的機器代碼按一定格式在Windows操作系統下就是Portable Executable File Format--PE文件格式)存儲在文件中,以便以後操作系統執行程序時能按照那個格式找到應該執行的第一條指令或其他東西,如資源等。至於為什麼中間還要加一個連接器以及其它細節,在後續文章中將會進一步說明。

4. Android性能優化總結

常用的Android性能優化方法:

一、布局優化:

1)盡量減少布局文件的層級。

層級少了,繪制的工作量也就少了,性能自然提高。

2)布局重用 <include標簽>

3)按需載入:使用ViewStub,它繼承自View,一種輕量級控制項,本身不參與任何的布局和繪制過程。他的layout參數里添加一個替換的布局文件,當它通過setVisibility或者inflate方法載入後,它就會被內部布局替換掉。

二、繪制優化:

基於onDraw會被調用多次,該方法內要避免兩類操作:

1)創建新的局部對象,導致大量垃圾對象的產生,從而導致頻繁的gc,降低程序的執行效率。

2)不要做耗時操作,搶CPU時間片,造成繪制很卡不流暢。

三、內存泄漏優化:

1)靜態變數導致內存泄漏   比較明顯

2)單例模式導致的內存泄漏 單例無法被垃圾回收,它持有的任何對象的引用都會導致該對象不會被gc。

3)屬性動畫導致內存泄漏  無限循環動畫,在activity中播放,但是onDestroy時沒有停止的話,動畫會一直播放下去,view被動畫持有,activity又被view持有,導致activity無法被回收。

四、響應速度優化:

1)避免在主線程做耗時操作 包括四大組件,因為四大組件都是運行在主線程的。

2)把一些創建大量對象等的初始化工作放在頁面回到前台之後,而不應該放到創建的時候。

五、ListView的優化:

1)使用convertView,走listView子View回收的一套:RecycleBin 機制

主要是維護了兩個數組,一個是mActiveViews,當前可見的view,一個是mScrapViews,當前不可見的view。當觸摸ListView並向上滑動時,ListView上部的一些OnScreen的View位置上移,並移除了ListView的屏幕范圍,此時這些OnScreen的View就變得不可見了,不可見的View叫做OffScreen的View,即這些View已經不在屏幕可見范圍內了,也可以叫做ScrapView,Scrap表示廢棄的意思,ScrapView的意思是這些OffScreen的View不再處於可以交互的Active狀態了。ListView會把那些ScrapView(即OffScreen的View)刪除,這樣就不用繪制這些本來就不可見的View了,同時,ListView會把這些刪除的ScrapView放入到RecycleBin中存起來,就像把暫時無用的資源放到回收站一樣。

當ListView的底部需要顯示新的View的時候,會從RecycleBin中取出一個ScrapView,將其作為convertView參數傳遞給Adapter的getView方法,從而達到View復用的目的,這樣就不必在Adapter的getView方法中執行LayoutInflater.inflate()方法了。

RecycleBin中有兩個重要的View數組,分別是mActiveViews和mScrapViews。這兩個數組中所存儲的View都是用來復用的,只不過mActiveViews中存儲的是OnScreen的View,這些View很有可能被直接復用;而mScrapViews中存儲的是OffScreen的View,這些View主要是用來間接復用的。

2)使用ViewHolder避免重復地findViewById

3)快速滑動不適合做大量非同步任務,結合滑動監聽,等滑動結束之後載入當前顯示在屏幕范圍的內容。

4)getView中避免做耗時操作,主要針對圖片:ImageLoader來處理(原理:三級緩存)

5)對於一個列表,如果刷新數據只是某一個item的數據,可以使用局部刷新,在列表數據量比較大的情況下,節省不少性能開銷。

六、Bitmap優化:

1)減少內存開支:圖片過大,超過控制項需要的大小的情況下,不要直接載入原圖,而是對圖片進行尺寸壓縮,方式是BitmapFactroy.Options 采樣,inSampleSize 轉成需要的尺寸的圖片。

2)減少流量開銷:對圖片進行質量壓縮,再上傳伺服器。圖片有三種存在形式:硬碟上時是file,網路傳輸時是stream,內存中是stream或bitmap,所謂的質量壓縮,它其實只能實現對file的影響,你可以把一個file轉成bitmap再轉成file,或者直接將一個bitmap轉成file時,這個最終的file是被壓縮過的,但是中間的bitmap並沒有被壓縮。bitmap.compress(Bitmap.CompressFormat.PNG,100,bos);

七、線程優化:

使用線程池。為什麼要用線程池?

1、從「為每個任務分配一個線程」轉換到「在線程池中執行任務」

2、通過重用現有的線程而不是創建新線程,可以處理多個請求在創建銷毀過程中產生的巨大開銷

3、當使用線程池時,在請求到來時間 ,不用等待系統重新創建新的線程,而是直接復用線程池中的線程,這樣可以提高響應性。

4、通過和適當調整線程池的大小 ,可以創建足夠多的線程以使處理器能夠保持忙碌狀態,同時還可以防止過多線程相互競爭資源而使應用程序耗盡內存或者失敗。

5、一個App裡面所有的任務都放在線程池中執行後,可以統一管理 ,當應用退出時,可以把程序中所有的線程統一關閉,避免了內存和CPU的消耗。

6、如果這個任務是一個循環調度任務,你則必須在這個界面onDetach方法把這個任務給cancel掉,如果是一個普通任務則可cancel,可不cancel,但是最好cancel

7、整個APP的總開關會在應用退出的時間把整個線程池全部關閉。

八、一些性能優化建議:

1)避免創建過多對象,造成頻繁的gc

2)不要過多使用枚舉,枚舉佔用的空間比整型大很多

3)字元串的拼接使用StringBuffer、StringBuilder來替代直接使用String,因為使用String會創建多個String對象,參考第一條。

4)適當使用軟引用,(弱引用就不太推薦了)

5)使用內存緩存和磁碟緩存。

5. 指令重排

指令重排序是JVM為了優化指令,提高程序運行效率,在不影響 單線程程序 執行結果的前提下,盡可能慶蠢地提高並行度。編譯器、處理器也遵循這樣一個目標敏差虛。注意是單線程。多線程的情況下指令重排序就會給程序員帶來問題。

指令重排可以分為兩種

指的是 編譯器 處理器 出於優化的目的按照某種規則將指令重新排序

由於 緩存同步順序 等問題,看起來指令被重排序了。

指令重排在單線程下可以優化程序的運行效率,單核時代的一切都是那麼完美。然而,多核時代出現了 可見性 問題。橋燃

6. int a[100] 這400個位元組的空間編譯時並不分配

編譯時當然不分配,運行時才分配。

編譯把源程序翻譯成機器指令:「給a分配100個單元,整型」
執行程序時,操作系統按指令分配,無所謂聰明不聰明。

熱點內容
安卓瀏覽圖片如何全屏 發布:2024-05-03 17:24:08 瀏覽:104
傳奇倉庫腳本 發布:2024-05-03 17:23:56 瀏覽:541
2010資料庫技術及應用 發布:2024-05-03 17:21:51 瀏覽:921
小米賬號密碼忘了怎麼 發布:2024-05-03 17:17:44 瀏覽:780
皇家農場腳本 發布:2024-05-03 16:46:41 瀏覽:458
順序存儲鏈式存儲 發布:2024-05-03 16:46:41 瀏覽:879
電腦配置低可以玩什麼fps游戲 發布:2024-05-03 16:46:39 瀏覽:421
qq刷紅包腳本 發布:2024-05-03 16:16:54 瀏覽:769
c服務編譯耗時優化原理及實例 發布:2024-05-03 15:35:26 瀏覽:15
ue編程 發布:2024-05-03 15:34:40 瀏覽:610