2011-10-19 44 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等启动起来非常缓慢的很大一部分原因。

就个人而言,我会去使用动态加载的模块为扩展工具,而不是作为一个发展模式的策略。