2011-10-19 45 views
5

我們有一個非常模塊化的應用程序,它有很多共享對象(.so)。有些人認爲,在內存/閃存有限的低端平臺上,最好將所有內容靜態鏈接到一個大的可執行文件中,因爲共享對象有開銷。共享對象開銷

您對此有何評論?

最好的問候,

保羅

回答

5

除非內存是極其緊張,這些文件的一個副本的大小不是主要決定因素。鑑於這是一個嵌入式系統,您可能很清楚哪些應用程序將使用您的庫以及何時使用您的庫。如果您的應用程序打開並關閉了多個庫,它會盡職盡責地引用,而且您不會同時打開所有庫,那麼共享庫將大大節省RAM。

您需要考慮的另一個因素是性能損失。打開一個共享庫需要很少的時間(通常是微不足道的)。如果您的處理器速度很慢或難以實時處理實時要求,則靜態庫不會導致共享庫的加載懲罰。配置文件,以查明這是否重要。總結一下,在一些特殊情況下,共享庫可能比靜態庫好得多。在大多數情況下,他們幾乎沒有傷害。在簡單的情況下,你不會從共享庫中受益。


當然,共享庫將是在Flash中顯著的儲蓄,如果你有多個應用程序(或應用程序的版本),它使用相同的庫。如果使用靜態庫,則將一個副本(與共享庫[1]大小相同)編譯到每個副本中。當你在PC工作站上時,這很有用。但你知道這一點。您正在使用僅由一個應用程序使用的庫。


[1]單個庫文件的內存差異很小。共享庫添加索引和符號表,以便dlopen(3)可以加載庫。這是否重要取決於您的使用情況;編譯每一個,然後比較大小以確定Flash中的哪個更小。你必須運行和配置文件來確定哪些消耗更多的RAM;除了共享庫的初始加載外,它們應該是相似的。

1

有很多,當然庫意味着更多的元數據必須存儲,並且還一些元數據(庫部分標題等)將需要加載時存儲在RAM中。但是,即使在(中等現代化的)嵌入式系統上,差異也應該可以忽略不計。

我建議你嘗試兩種選擇,並在FLASH和RAM中測量已用空間,然後確定哪一個最好。

6

共享庫的成本大致(每個庫):

  • 至少的私人髒存儲器4K。
  • 至少12k的虛擬地址空間。
  • 幾個文件系統訪問系統調用,mmapmprotect系統調用,並在加載時至少一個頁面錯誤。
  • 解決庫代碼中符號引用的時間。

加上位置無關的代碼的成本:

  • 損失一個通用寄存器(這可以在x86(32位),但大多其他archs無關巨大)。
  • 間接訪問全局/靜態變量(和常量)的額外級別。

如果你有一個長時間運行的應用程序,那麼你的成本可能根本無關緊要,除非你在一個小巧的嵌入式系統上。另一方面,如果你正在寫一些可能被短時間任務調用的東西(比如語言翻譯),這些成本可能會很大。將所有標準模塊放在自己的.so文件中,而不是默認靜態鏈接它們,這是Perl,Python等啓動起來非常緩慢的很大一部分原因。

就個人而言,我會去使用動態加載的模塊爲擴展工具,而不是作爲一個發展模式的策略。