为什么游戏引擎更喜欢静态库而不是动态链接库?

20

我一直在阅读一些游戏书籍。它们总是更喜欢创建静态库作为引擎而非动态链接。我对C++是新手,所以对于静态库和动态链接库并不了解得很深入。我只知道静态库会增加程序的大小,而 DLL 链接库则会在您的程序中需要时加载。

[编辑]

我玩过一些游戏,似乎它们都使用 DLL 来单独加载声音、光线等等内容,当关卡开始加载时再进行加载。因为当您在游戏菜单时并不一定需要这些内容。


3
他们更有可能在需要时加载艺术和声音资产,而不是选择在后期加载DLL。通常,你需要从一开始就拥有所有功能,但并非所有数据都需要同时加载。 - Kylotan
5个回答

21
动态链接库需要是位置无关的;这可能会在某些处理器架构上导致性能效率低下。
静态库可以在包含在程序中时进行优化,例如删除死代码。这可以提高缓存性能。

1
好的,您说它们需要位置无关。请定义位置无关。因为我的理解是,DLL和静态库都可以被认为是独立的,因为它们不属于初始游戏。当您使用静态库时,您会加载其所有内容。那么您如何从中去除死代码? - numerical25
6
静态库在编译/链接时与可执行文件一起链接;链接器知道静态库代码的加载地址,并可以进行优化。链接器还知道库中被引用的函数,并可以剥离未被引用的函数。动态库在运行时链接,并且可能由多个进程共享,因此其地址不能预先知道,也不能移动。动态库具有动态使用的入口点(duh);-),因此不能从内存占用中消除任何代码。 - Doug Currie
2
“位置无关”是指代码必须能够在内存中的任何位置运行。这意味着使用相对跳转和基于指针的数据引用(或PC相对常量数据引用)。非常智能的加载器可能会在加载时进行一些工作以最小化影响。然而,静态代码可以编译和链接以使用已知地址的数据和代码。 - Doug Currie
@Doug “非常聪明的装载程序可能会……” 实际上,即使是聪明的程序,在系统允许两个同时使用它的进程在不同的虚拟地址下看到同一个动态库时,也会很难做到。例如,在 ELF 二进制格式中有这个选择,我不太了解其他格式。 - Pascal Cuoq
@Pascal:嗯,Windows主要运行在x86上,其可变宽度指令使得在加载时反汇编dll文件变得不可能,因此Windows不能改变二进制文件。 - BlueRaja - Danny Pflughoeft
2
如果一个DLL被保证在所有使用它的进程中看到的地址相同,那么预链接它就不需要反汇编。旧的a.out格式可以做到这一点,但这是不切实际的(集中式全球DLL机构)。我认为Mac OS X也可能有类似的东西(但中心化仅在计算机规模上)。 - Pascal Cuoq

9
他所说的“位置独立”是指游戏引擎和DLL完全分离,DLL是独立的,不能与游戏引擎代码交织在一起。而静态链接库允许编译器使用你的游戏引擎代码和库代码进行优化。
例如,假设有一个小函数,编译器认为应该内联(直接复制到函数调用的位置)。然后,在使用静态库时,编译器将能够内联此代码,因为它“知道”代码是什么(在编译时进行链接)。但是,在使用动态库时,编译器将无法内联该代码,因为它“不知道”代码是什么(因为它将在运行时链接) 。

内联不是动态库速度较慢的原因。大多数编译器+链接器不会跨文件内联函数。实际上,我使用一种语言进行编程,在该语言中编译器会跨文件进行内嵌,导致真正的分离式编译的缺失令我非常烦恼。 - Pascal Cuoq
没错。我只是举例说明内联可能是使用静态库而不是动态库的一个具体示例。 - foxwoods
3
Visual Studio具有整个程序优化功能,可以高兴地在文件之间甚至可能跨库进行内联。如果gcc没有类似的功能,我会感到惊讶(尽管大多数游戏不会在gcc中编译)。 - Kylotan

3
另一个常常被忽视的原因值得一提,那就是对于很多游戏来说,你不需要运行许多其他的东西,而且用于游戏的许多库也不会被用于与游戏同时运行的其他事情,所以你不必担心使用共享库带来的主要优势之一,即只需在一次加载(大部分)库时加载一次,而多个东西可以利用这一个副本。当运行游戏时,你可能只有一个想要使用该库的程序正在运行,因为你可能不会同时运行许多其他程序(特别是其他游戏或3D程序)。
此外,你还可以开启全局/链接时间优化,这在使用共享库时要困难得多。

2
另一个问题涵盖了静态库和动态库的区别:什么时候使用动态库和静态库 至于为什么要使用静态库,额外的速度可能是值得的,而且可以避免DLL地狱(过去是个大问题)。如果您想要一起分发程序和库,则非常有用,确保接收者具有正确的依赖性,虽然您也可以将DLL与可执行文件一起分发。

2

当为游戏主机开发游戏时,通常动态链接不是一个选项。如果您想将引擎用于主机和PC开发,最好避免使用动态链接。


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