我們有一個非常模塊化的應用程序,它有很多共享對象(.so)。有些人認爲,在內存/閃存有限的低端平臺上,最好將所有內容靜態鏈接到一個大的可執行文件中,因爲共享對象有開銷。共享對象開銷
您對此有何評論?
最好的問候,
保羅
我們有一個非常模塊化的應用程序,它有很多共享對象(.so)。有些人認爲,在內存/閃存有限的低端平臺上,最好將所有內容靜態鏈接到一個大的可執行文件中,因爲共享對象有開銷。共享對象開銷
您對此有何評論?
最好的問候,
保羅
除非內存是極其緊張,這些文件的一個副本的大小不是主要決定因素。鑑於這是一個嵌入式系統,您可能很清楚哪些應用程序將使用您的庫以及何時使用您的庫。如果您的應用程序打開並關閉了多個庫,它會盡職盡責地引用,而且您不會同時打開所有庫,那麼共享庫將大大節省RAM。
您需要考慮的另一個因素是性能損失。打開一個共享庫需要很少的時間(通常是微不足道的)。如果您的處理器速度很慢或難以實時處理實時要求,則靜態庫不會導致共享庫的加載懲罰。配置文件,以查明這是否重要。總結一下,在一些特殊情況下,共享庫可能比靜態庫好得多。在大多數情況下,他們幾乎沒有傷害。在簡單的情況下,你不會從共享庫中受益。
當然,共享庫將是在Flash中顯著的儲蓄,如果你有多個應用程序(或應用程序的版本),它使用相同的庫。如果使用靜態庫,則將一個副本(與共享庫[1]大小相同)編譯到每個副本中。當你在PC工作站上時,這很有用。但你知道這一點。您正在使用僅由一個應用程序使用的庫。
[1]單個庫文件的內存差異很小。共享庫添加索引和符號表,以便dlopen(3)
可以加載庫。這是否重要取決於您的使用情況;編譯每一個,然後比較大小以確定Flash中的哪個更小。你必須運行和配置文件來確定哪些消耗更多的RAM;除了共享庫的初始加載外,它們應該是相似的。
有很多,當然庫意味着更多的元數據必須存儲,並且還一些元數據(庫部分標題等)將需要加載時存儲在RAM中。但是,即使在(中等現代化的)嵌入式系統上,差異也應該可以忽略不計。
我建議你嘗試兩種選擇,並在FLASH和RAM中測量已用空間,然後確定哪一個最好。
共享庫的成本大致(每個庫):
mmap
和mprotect
系統調用,並在加載時至少一個頁面錯誤。加上位置無關的代碼的成本:
如果你有一個長時間運行的應用程序,那麼你的成本可能根本無關緊要,除非你在一個小巧的嵌入式系統上。另一方面,如果你正在寫一些可能被短時間任務調用的東西(比如語言翻譯),這些成本可能會很大。將所有標準模塊放在自己的.so
文件中,而不是默認靜態鏈接它們,這是Perl,Python等啓動起來非常緩慢的很大一部分原因。
就個人而言,我會去使用動態加載的模塊爲擴展工具,而不是作爲一個發展模式的策略。