DLL函数调用的开销

7

调用DLL函数时会出现性能损失吗?对我们来说,加载DLL不是问题,我们高性能库的调用次数也不会很多。

大约一次DLL函数调用需要多少条指令/时钟周期,相比静态库调用呢?


可能是DLL开销的重复问题。 - Alok Save
1个回答

12

我的答案是基于Linux/glibc/ELF动态链接器的工作方式,但我认为其他平台的总体答案也是相同的:

第一次调用动态加载的符号与后续调用之间存在差异。第一次调用很昂贵,可能需要很多周期。所有其他调用都更多或少距离1-2个指令。

它的工作原理是链接器在过程链接表中设置一个条目,该条目从全局偏移表中获取那个外部函数的地址。在首次调用时,GOT的地址指向运行动态链接器以解析DLL中函数的实际地址的存根。这可能需要很多周期,但是一旦完成一次,动态链接器将修改GOT条目的路径,直接指向该函数,因此下一次调用PLT代码时将直接调用该函数。

这里是一个非常好的演示该过程的链接:http://www.technovelty.org/linux/pltgot.html


1
在Windows上的DLL中,所有这些工作都是由加载器在模块加载时完成的。 - David Heffernan
我相信只有在DLL没有使用LoadLibrary进行动态加载时才是真的。 - Tamás Szelei
@Tamas:为什么?因为我们需要运行时加载。 - Cartesius00
1
@Tamás Szelei 是的,当您使用LoadLibrary时,加载它需要成本,每次调用GetProcAddress时都需要支付更多费用。 - David Heffernan
@James,如果你在PE头中有DLL,Win32 PE加载器将在运行时加载你的DLL(就像David建议的那样,在执行开始之前)。如果你动态加载一个库,你可以使用GetProcAddress获取函数指针,从那个点开始,它的开销基本上与另一种情况相同。 - Tamás Szelei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接