C 應用程式效能優化 程式的啟動過程

2021-07-15 03:02:05 字數 2062 閱讀 3498

1. 重定位:

目標檔案一般由多個節組成,編譯器在編譯每個目標檔案時一般都是從0位址開始生成**。當多個**節合成乙個**段時,需要根據其在最終**段中的位置做出調整。同時,鏈結器需要對已經解析的符號分配執行時位址。這個過程就是重定位。

載入時重定位:

程式中可能呼叫了dll,由於exe是最先被載入的,所以一般都能載入到其想要的記憶體位址上;而dll的載入一般在exe之後,就需要對dll中的位址進行重定位了。

2. 程式的啟動過程

win32程式啟動過程包括:

(1) 作業系統把程式載入到記憶體,並建立相應的執行環境

(2) 應用程式自身的初始化過程

備註:應用程式必須符合pe格式,主要包含:data(資料段),.text(**段)。資料和**載入到記憶體中後,cpu從程式入口處按順序取出每一條指令並執行。

記憶體中,應用程式的**表現為一系列有序的指令集。

載入器:作業系統載入器的任務是,把磁碟中可執行程式的物理檔案讀入記憶體,並轉換成程式在記憶體中的表示。

3. 編譯鏈結和啟動

(1) 預編譯展開巨集

(3) 編譯器合成這些目標檔案成乙個庫檔案(.lib),同時解析可以找到的符號引用

(4) 鏈結器把目標庫檔案和所有需要引用的靜態、動態庫進行鏈結,生成最終的可執行檔案。(首先需要把依賴的靜態庫合成到可執行檔案中,其次要保證依賴的動態庫檔案的符號都存在)可執行檔案的符號表只需要記錄匯入符號表。

啟動:

不依賴dll的程式:

(1) 作業系統建立程序並分配私有的程序空間;

(2) 載入器把可執行檔案的資料段和**段對映到程序虛擬記憶體中;

(3)預取有限的**段進入實際記憶體,把cpu的ip指向程式入口點,即可開始執行

依賴dll的程式:

(1) 同上,建立程序、對映虛擬記憶體;

(2) 載入器讀取可執行檔案的匯入符號表,由此找到依賴的dll

(3) 載入器對依賴的每個dll呼叫loadlibrary

loadlibrary中處理的事情如下:

a. 載入器為該dll確定乙個合適的基位址(位址重定位)

b. 讀取匯入和匯出符號表,比較應用程式的匯入符號與dll的匯出符號是否匹配

c. 通過dll匯入符號表確定該dll所依賴的其他dll,同樣載入起來

d. 呼叫dll的初始化函式

(4) 初始化應用程式的全域性變數

(5) 進入應用程式入口點函式開始執行

4. 影響啟動效能的因素:

(1) 程式冷啟動的效能大部分取決於io操作消耗的時間;

(2) dll匯出過多符號,會引起載入器耗費過多的cpu事件和io來處理這個符號表;

(3) 磁碟碎片問題:理想狀態下,順序讀取乙個檔案,不需要磁頭尋道操作。但作業系統的檔案系統,以塊為單位管理物理磁碟空間,當磁碟經過不斷的增刪改操作後,可能不再具有連續的儲存空間。導致乙個邏輯上連續的檔案,在磁碟上由很多不連續的碎片組成,導致執行io時需要過多的尋道時間。

5. 優化啟動過程的方法:

(1) 減少動態庫數量;

(2) 減小動態庫的尺寸:可以通過編譯優化選項;清除冗餘**;

(3) 優化可執行檔案和庫檔案的**布局:把庫檔案中的函式排的更緊密,從而達到減少io的目的;

(4)延遲初始化:可以把一些啟動初期不需要的初始化工作延遲到啟動後,增強啟動體驗;延遲的時機:可以在程式空閒時進行處理,在訊息迴圈空閒時處理。

(5) 多執行緒化啟動:具有以下特點,適合多執行緒化啟動

啟動時需要載入大量動態庫,引發大量io操作;同時這些動態庫初始化函式需要執行密集型操作,占用cpu時間。這時候可以將io等待時間和cpu執行時間交錯處理,縮短啟動時間。

備註:io的實現,是cpu發出命令後,由主機板dmp完成,完成後觸發中斷,然後cpu繼續處理,所以io占用的cpu時間很少。

C 應用程式效能優化

本文選自c 應用程式效能優化 第2版 一書 總 序 去國離家十六載後,2006年,當我再次歸來凝視上海這座不夜城時,不由地感慨世界真的變小了 變平了,中國作為地球村的一員,正以驚人的速度發展變化著。世界正改變著中國,中國也不斷影響著世界。在備感欣喜振奮之餘,我亦常常思索,在乙個越來越小 越來越平的世...

C 應用程式效能優化

本文選自一書 總 序 去國離家十六載後,2006年,當我再次歸來凝視上海這座不夜城時,不由地感慨世界真的變小了 變平了,中國作為地球村的一員,正以驚人的速度發展變化著。世界正改變著中國,中國也不斷影響著世界。在備感欣喜振奮之餘,我亦常常思索,在乙個越來越小 越來越平的世界裡,中國會面對怎樣的挑戰和機...

WPF 應用程式效能優化

開發效率 能使用xaml實現的就不使用者cs後台程式編寫 資料繫結 資料繫結使用的是屬性,不是字段 public observablecollectionlist new observablecollection dispatcher.invoke dispatcherpriority.backgr...