【发布时间】:2011-10-19 11:44:43
【问题描述】:
我们有一个非常模块化的应用程序,其中包含许多共享对象 (.so)。有人认为,在内存/闪存有限的低端平台上,最好将所有内容静态链接到一个大的可执行文件中,因为共享对象有开销。
您对此有何看法?
最好的问候,
保罗
【问题讨论】:
标签: c linux embedded shared-libraries
我们有一个非常模块化的应用程序,其中包含许多共享对象 (.so)。有人认为,在内存/闪存有限的低端平台上,最好将所有内容静态链接到一个大的可执行文件中,因为共享对象有开销。
您对此有何看法?
最好的问候,
保罗
【问题讨论】:
标签: c linux embedded shared-libraries
共享库的成本大致为(每个库):
mmap 和 mprotect 系统调用,以及加载时至少一个页面错误。加上与位置无关的代码成本:
如果您有一个大型的长期运行的应用程序,那么成本对您来说可能根本不重要,除非您使用的是小型嵌入式系统。另一方面,如果您正在编写一些可能会为短期任务(如语言解释器)多次调用的东西,那么这些成本可能是巨大的。将所有标准模块放在它们自己的 .so 文件中而不是默认静态链接它们是 Perl、Python 等启动如此缓慢的重要原因。
就个人而言,我会采用将动态加载模块用作可扩展性工具而不是开发模型的策略。
【讨论】:
除非内存非常紧张,否则这些文件的一份副本的大小不是主要的决定因素。鉴于这是一个嵌入式系统,您可能很清楚哪些应用程序将使用您的库以及何时使用。如果您的应用程序打开和关闭它尽职尽责地引用的多个库,并且您永远不会同时打开所有库,那么共享库将显着节省 RAM。
您需要考虑的另一个因素是性能损失。打开共享库需要一小段时间(通常是微不足道的);如果您有一个非常慢的处理器或难以满足实时要求,则静态库不会导致共享库的加载损失。分析以确定这是否重要。
综上所述,在某些特殊情况下,共享库可以明显优于静态库。在大多数情况下,它们几乎没有伤害。在简单的情况下,您不会从共享库中获益。
当然,如果您有多个使用同一个库的应用程序(或应用程序的版本),共享库将在 Flash 中节省大量资金。如果您使用静态库,则会将一个副本(与共享库 [1] 的大小大致相同)编译到每个库中。当您在 PC 工作站上时,这很有用。但你知道的。您正在使用一个仅由一个应用程序使用的库。
[1] 各个库文件的内存差异很小。共享库添加索引和符号表,以便dlopen(3) 可以加载库。这是否重要取决于您的用例;为每个编译,然后比较大小以确定 Flash 中哪个更小。您必须运行并分析以确定哪个消耗更多 RAM;除了共享库的初始加载之外,它们应该是相似的。
【讨论】:
拥有大量库当然意味着必须存储更多元数据,并且在加载时需要将其中一些元数据(库节标题等)存储在 RAM 中。但即使在(中等现代的)嵌入式系统上,差异也应该可以忽略不计。
我建议你尝试这两种方案,并测量 FLASH 和 RAM 中的已用空间,然后决定哪个最好。
【讨论】: