是否有任何有说服力的性能理由选择静态链接,通过在特定情况下的动态链接或签证反之亦然?我已听到或阅读以下内容,但我不知道足够的关于该主题以保证其真实性。

1) 性能之间静态链接和动态链接之处在于通常可以忽略不计。

2) (1) 不使用分析编译器使用的配置文件数据进行优化程序 hotpaths,因为静态链接的情况下,编译器可以优化您的代码和库代码的情况下为 true。使用动态链接您的代码可以进行优化。如果花费大部分时间的运行库代码,这会使有很大差别。否则,(1) 仍然适用。

2010-01-03 00:06:12
问题评论:

"静态链接的情况下,可以优化编译器.库代码"但仅当对其进行编译,太 !如果只是链接预编译的对象文件,编译器没有得到以优化它们的机会。

如果是这样,然后是正确的但没有关于如何真正的是与现代编译器,如果有人可以验证这一种方式或另一种就更好了的一些问题。

与编译器编译为本机代码 (如大多数 C/c + + 编译器) 是不会再对代码进行优化的机会。如果在某些中间语言 (如.Net IL) 编译代码,调用 JIT 编译器时已加载库进行编译为本机代码中。最终编译可以使用时间随着 JIT 编译器的发展越来越多地更好。

@Eloff: VS2008 对待所 LTCG 启用。(lib 文件变得巨大无比,但..)我已经 toyed 周围与之并对某人感兴趣,"可我编译器为我做什么",是惊人的意义。

回答:

  • 动态链接可以减少总的资源占用(如果多个进程共享同一个库 (当然包括在"相同",版本))。我相信这是参数驱动它的存在在大多数环境中。这里"资源"包括磁盘空间、 内存,以及缓存空间。当然,缺乏灵活动态的链接器是否存在着某种风险的DLL hell.
  • 动态链接意味着该 bug 修复和升级到库传播以提高的产品而不需要您提供的任何内容。
  • 动态链接的始终调用插件
  • 静态链接中,意味着您可以知道代码将运行在非常有限的环境(在启动过程中,早期或拯救模式)。
  • 静态链接可以使二进制文件方便地分发到不同的用户环境 (但会使发送较大,而更多资源饿的时候启动程序)。
  • 静态链接可能允许略有更快的启动时间,但这取决于某种程度的大小和复杂的程序操作系统装载策略的详细信息。

包括非常相关的建议,在注释和其他答案中某些编辑操作。我想要注意休息,这取决于在什么环境打算运行的很多的方式。最小的嵌入式的系统可能没有足够的资源来支持动态链接。稍大一点的小系统也可能支持链接,,因为它们的内存是足够小,能够使从动态链接的 RAM 节约非常吸引人。完整的吹制使用者个人电脑,便利问题可能允许标记笔记、 巨大的资源,并可以推动您想在此问题上。


为了解决性能和效率问题︰它依赖于.

通常情况下,动态库需要某种的胶水层,这通常意味着使用双调度或额外的间接寻址功能解决和代价有点速度 (但实际运行时间的重要部分是函数调用时间窗)。

但是,如果您正在运行多个进程的所有大量调用同一个库,您可以结束最多保存缓存行 (和因此获胜的运行性能) 时使用的动态链接相对使用静态链接。(除非现代操作系统的智能,足以请注意静态链接的二进制文件中的相同部分。似乎很难,任何人都知道吗?)

另一个问题︰ 加载时间。在某些时候,您支付加载成本。当您支付此成本取决于操作系统原理以及使用什么链接。也许您宁愿把关闭它支付,直到您知道您需要它。

请注意,静态 vs-动态链接过去优化的问题,因为它们都涉及对象文件到单独的编译。但是,这不是必需︰ 编译器可以在原则上,"编译"到 digested AST 窗体的"静态库"最初,和""链接来链接到主代码,从而使全局优化生成的添加这些 Ast。没有任何系统使用,这样做我不能对它的工作如何更好地发表评论。

方式来回答性能始终是通过测试 (并使用更喜欢尽可能的部署环境的测试环境)。

资源消耗基本上是关注的代码空间,即随着时间的推移越来越少。如果 500k 的库的 2 MB 节约,这是 5 个进程之间共享小于。 3 gb 的 RAM 的 1%。

如果库还共享同一个虚拟映射 (同一物理和虚拟地址在所有进程中),不动态链接也将保存 TLB 插槽中 MMU 的处理器?

此外动态链接很容易使用更好的版本来更新错误的库代码。

它也很容易将错误代码添加到一个工作版本的 @Zan。

另一种情况,您应该使用动态链接是已编译的程序,与嵌入的预计与已编译的程序共享代码解释器。例如,编写 c + + 中,但与 Lua 扩展它们需要加载共享库通过相同的 c + + 代码的一些游戏。如果静态链接这样的应用程序,和一些它的代码从共享库加载"第二次",则会导致未定义的行为 (在 c + + 示例中它可以是一个定义规则或 ODR 的冲突)。有几种方法可解决此问题,但是"混合"程序倾向于动态链接。

动态链接是满足一些如LGPL许可的要求的唯一可行办法.

LGPL,只要最终用户可以重新链接到将代码 (例如因为与您的软件提供您的源代码或已编译的对象文件),然后静态链接很好此外,如果您的软件是供内部使用 (也就是只,您的组织内使用和未分配),则可以静态链接。这将应用于如服务器软件,何处不分发服务器。

听明白。能您给我要感激您编写了多个源 (或精心设计的更多)?

@Thorn 请参阅LGPL 许可部分 4.d+e既需要分发表单要求用户执行链接操作或分发 (动态) 的共享的库中。

1) 是根据事实来调用的 DLL 函数总是使用额外间接跳转。而这正是今天通常可以忽略不计。在该 DLL 内还有一些更多的系统开销在 i386 CPU 的因为他们不能生成的位置无关的代码-在 amd64 跳可以相对于程序计数器因此这是一个巨大的改进。

2) 这是正确的。通常可以通过使用配置文件导引优化赢得大约 10-15%的性能。现在其中 CPU 速度已达到其限制,但可能值得这样做。

(3) 方式添加链接器可以安排更多高速缓存相干性分组,以便尽量降低了昂贵的高速缓存级别失误中的函数。它也可能影响关闭应用程序的启动时间。

另外,不要忘记,没有死代码的 DLL 的可执行消除。这取决于语言的 DLL 代码可能不是最佳也编译。虚函数都虚拟,因为编译器不知道客户端是否覆盖它。

为此原因如果不真正需要的 DLL 的只是使用静态编译。

编辑 (以下划线回答注释)

以下是有关位置无关的代码问题http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/出色的资源

解释了的 x86 不具有这些 AFAIK 任何其他内容,然后 15 位跳转范围而不是用于调用。这是函数 (从生成器) 有更多然后 32k 为什么总是已出现问题并需要嵌入 trampolines。

但在流行 x86 操作系统喜欢的 Linux 就不需要在意因为像正常链接器将重新调整其位置只需固定如果没有代码-fpic (这会强制使用间接跳转表) 不生成等或动态链接库文件。但在这样做时它使代码段非可共享,需要的代码的完整映射到内存和接触全部清空缓存的大部分 (命中 TLB 的) 才能使用等。有当时这被认为是当...降低速度缓慢。

因此您将不再拥有任何优势。

我不记得什么操作系统给我带来了我的 unix 生成系统的问题因为我只需要不这样,想知道为什么崩溃直到 i gcc 应用-fPIC。

我喜欢此回答,因为它是唯一一个为了解决我问题中引发点。

一定会非常有趣,让这些 DLL 技术信息,和在不同的操作系统之间进行比较的参照。

似乎很正常,但 CPU 速度肯定未达到极限。

我同意点 dnmckee 提及,再加上︰

  • 静态链接的应用程序可能不易于部署,因为有较少或根本没有其他文件依赖项 (.dll /.so) 时,其缺失或安装在错误的地方,可能会导致一些问题。

值得注意,转到编译器从 Google 将会只有静态编译的二进制文件的主要是这个原因。

@Hut8 不是这样的。绝对拒绝提供链接静态 c + + 库到现在。

执行静态链接的生成的一个原因是确认您具有全封闭的可执行文件,即正确解析符号的所有引用。

作为已正在生成和测试时使用持续集成的大型系统的一部分,使用的是静态链接的可执行文件的版本运行夜间的回归测试。有时,我们会看到,符号将不能解决,即使动态链接的可执行文件都可以成功链接,静态链接会失败。

这通常发生时已深,固定在共享库中的符号有 misspelt 的名,并因此将静态链接。动态链接器不能完全解决所有的符号,而不考虑使用深度优先或广度第一个求值,因此您可以完成与动态链接的可执行文件,不具有全封闭。

很好点,我已经被尝试执行此操作,我在工作中有一些代码的最近,但编译静态证明非常令人讨厌的一切,只是放弃了

内容来源于Stack Overflow Static linking vs dynamic linking
请输入您的翻译

Static linking vs dynamic linking

确认取消