2010-01-08 83 views
7

我有一個關於共享庫vs靜態庫加載時間的問題。共享庫vs靜態庫加載時間

假設我有一個使用liba,libb,libc的可執行文件foo.exe。同時在給定的時間,機器上運行的可執行文件超過10個。

現在,如果上述3個庫是共享庫: 第一次Insance加載到RAM中:花費的時間將是foo.exe的main()被加載的內存(假設其可忽略不計)+加載時間liba +加載libb的時間+加載libc的時間 第二個實例已啓動:現在假設運行此可執行文件的第二個實例。由於所有的庫文件 已經加載到主存儲器中,所花費的時間僅用於將main()加載到可忽略的存儲器中。

現在,如果上述3個圖書館是靜態庫: 第一Insance被加載到RAM:採取將通過主)foo.exe的採取(時間的時間被加載 存儲器(假設其忽略不計)+時間加載liba +加載libb的時間+加載libc的時間(Offcourse它現在是整個可執行文件的所有部分) 第二個實例已啓動:現在假設運行此可執行文件的第二個實例。所花費的時間將會是 再次由foo.exe的main()加載內存所花費的時間(假設其可忽略不計)+加載liba +時間加載libb +加載libc所需的時間。 (因爲每個可執行文件不能共享庫,因爲它們是靜態庫)

所以我的結論是,使用靜態庫的時候會更多。但是我被告知共享庫在加載過程中比靜態庫需要更多的時間,所以會有延遲,所以共享庫不是一個好的選擇。這怎麼可能 ?

回答

9

鏈接(解析引用)不是免費的。通過靜態鏈接,生成二進制文件時可以一勞永逸地完成分辨率。通過動態鏈接,每次加載二進制文件時都必須完成。更不用說編譯爲在共享庫中運行的代碼可能比編譯爲靜態鏈接的代碼效率低。確切的成本取決於體系結構和系統實現的動態鏈接。

對於32位x86指令集,動態生成庫的成本可能相對較高:在ELF binary format中,必須犧牲其中一個已稀缺的寄存器來使動態鏈接的代碼可重新定位。較早的a.out格式將每個共享庫放置在一個固定的位置,但這並沒有擴展。我相信當動態庫放置在地址空間中的預定位置時,Mac OS X具有中間系統,但是衝突在單個計算機的規模下解決(在安裝新的系統後冗長的「優化系統性能」階段軟件)。從某種意義上說,這個系統(稱爲pre-binding)可以讓你擁有你的蛋糕並且也可以吃它。 我不知道蘋果公司現在是否已經切換到amd64架構,是否還需要預先綁定。

此外,在現代操作系統上,靜態和動態鏈接的代碼僅在磁盤上加載(分頁)(如果使用的話),但這與您的問題非常相關。

+0

非常感謝這個令人難以置信的快速反應,我們有2個架構的場景,我已經給我的問題作爲我的問題的答案請在下面找到它。 – sud

2

靜態庫在編譯時鏈接,共享庫在運行時鏈接。因此,即使在寫入磁盤之前,使用靜態庫的可執行文件也會將其所有鏈接時間分攤。

+0

如果有3個庫力霸,libb,libc的都是靜態庫。現在兩個可執行文件foo1.exe和foo2.exe使用全部3個lib。 1.如果運行foo1.exe的多個實例,它們將共享文本頁面。這是正確的嗎 ? 2.如果foo1.exe和foo2.exe同時運行,它們將不共享文本頁面。這是正確的嗎 ? 請讓我知道 – sud

+0

在第一種情況下,共享的文本頁面將是foo1的文本頁面,而不是實際的庫文件,因爲庫在靜態鏈接之後不再存在。否則,兩者都是正確的。 –

0

非常感謝這個令人難以置信的快速響應。我們有2個架構圖:

Q1。架構-1:假設exe大小3GB(靜態庫)。 95%的是庫和5%的main()。如果這麼大的尺寸會導致這個exe的加載花費更多的時間(假設靜態庫),或者這個exe的鏈接需要更多的時間(假設使用共享庫,並且如果所有庫都已經在內存中只有鏈接必須完成)。

建築-2:假設我有一個exe文件大小爲1.5GB(95%lib + 5%main()),並且它的6個實例同時運行。一旦這6個實例結束,它們將運行數天,假設我們已準備好在這6個實例的初始加載+鏈接期間採取額外的延遲。 Q2302。現在,如果我使用共享對象而不是靜態對象,那麼我是否會在RAM上擁有大量可用空間,因爲所有庫都在6個實例之間共享?我的實時執行不會加速,因爲RAM中有更多空間會減少頁面交換?

Q3。如果我使用'map'文件來減少導出符號的數量(這隻能使用共享庫),那麼我的符號表大小是否會減少並且不會提高運行時性能?

感謝 南基

+0

如果您的意思是運行相同程序的實例(原始問題中的「foo.exe」),則代碼將在內存中共享(具有所有優點),靜態鏈接版本與動態鏈接版本相同。 –

+0

只有你的意思是略有不同的程序foo1.exe,foo2.exe每個使用相同的liba,libb,lic纔會有動態鏈接的優勢。在這種情況下,只有它可以分享一些無法與靜態鏈接共享的內容。 –

+0

其實我的意思是說,相同的可執行文件foo.exe(使用靜態庫)有6個實例,而不是foo1,foo2。但在這種情況下,代碼將如何在內存中共享?每個實例都有它自己的副本在RAM中?我以爲只有共享庫纔會共享,而不是靜態庫。你能提供一個可以啓發我的網址嗎? – sud