为 32 位或 64 位编译

Compile for 32 bit or 64 bit

我正在编写一个应用程序,我想知道我应该在 32 位模式还是 64 位模式下编译它。该程序不使用任何 64 位类型,也不访问超过 4 GB 的内存(而且我不打算访问那么多内存)。我可以看到使用 64 位模式相对于 32 位模式的唯一优势是 64 位模式允许访问更多的寄存器,但是在大多数情况下使用 32 位模式相对于 64 位模式肯定有一些好处的 64 位功能没有被使用(除了更小的指令和指针,因为我不担心我的程序溢出缓存)。使用 32 位是否有一些好处,例如更快的指令或更少的能耗,这应该导致我改为编译 32 位。谢谢。

使用 64 位,因为 运行32 位在 64 位环境中有开销(尽管很小)。

为什么不同时编译它?

我推荐 64 位 (AMD 64)。 32 位 (x86) 应用程序除了与真正的旧计算机兼容之外没有其他优势。我相信比我更有知识的人可以指出 AMD 64 相对于 x86 的一些技术优势,但我怀疑这些不会对您的普通应用程序产生真正的影响。

但是没有什么能阻止您编译和分发两者。

取决于应用类型。

正如其他人所提到的,32 位平台已被弃用,运行 64 位平台上的 32 位应用程序会产生一些开销。另外,正如您所说,编译器可以访问的寄存器更多,指令集更高级。

OTOH 在某些情况下,针对 32 位编译的代码将具有显着优势,因为本机指针大小较小。

例如,我有一个带有 "algorithmic" 代码的应用程序,它处理存储在具有 cross-pointers 的复杂数据结构中的大型数据集。为 32 位平台编译的相同应用程序内存占用明显减少,运行速度明显加快。

因此,如果您的应用程序未达到 32 位限制,使用具有本机指针的复杂数据结构,并且性能至关重要 - 32 位可能是一种可行的方法。否则我建议切换到 64 位。

WoW64 on Intel 64 (AMD64 / x64) 不需要指令仿真。在这种情况下,WoW64 子系统通过 32 位应用程序和 64 位 Windows API 之间的附加层仅模拟 32 位环境。有的地方这层薄,有的地方厚一点。对于一个普通的程序,你可能会因为这一层而预计到 2% 的性能损失。对于某些程序,它可能更大。百分之二不是很多,但请记住,32 位应用程序在 64 位环境下的运行速度 Windows 比在 32 位环境下要慢一些。

编译 64 位代码不仅可以让您避免使用 WoW64,还可以让您获得额外的性能提升。这可以通过微处理器中的架构修改来解释,例如增加 general-purpose 寄存器的数量。对于一般的程序,您可能期望仅在重新编译后就有 5-15% 的性能提升。

由于 WoW64 层,32 位程序在 64 位环境中的效率低于其本机 32 位环境。但是,简单的 32 位应用程序仍然可以获得在 64 位环境中执行的好处之一。也许您知道,如果使用开关“/3gb”启动 32 位 Windows,则使用开关“/LARGEADDRESSAWARE:YES”构建的程序最多可以分配 3 GB 的内存。那么,在 64 位系统上构建的同一个 32 位程序可以分配将近 4 GB 的内存(实际上通常约为 3.5 GB)。

P.S。另见 "Lesson 2. Support of 32-bit applications in the 64-bit Windows environment".

您在 64 位模式下的寄存器访问改进是正确的,但您可能不知道差异有多大。

Per Wikipedia:

Starting with the AMD Opteron processor, the x86 architecture extended the 32-bit registers into 64-bit registers in a way similar to how the 16 to 32-bit extension took place. An R-prefix identifies the 64-bit registers (RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, RFLAGS, RIP), and eight additional 64-bit general registers (R8-R15) were also introduced in the creation of x86-64. However, these extensions are only usable in 64-bit mode ...

在 x86 上,运行 在 64 位模式下,您可以访问 16 个 64 位寄存器。在32位模式下,只能访问8个32位寄存器。

并且由于在任何情况下三个寄存器都是程序计数器、堆栈指针和帧指针,可用 general-purpose 寄存器的差异更加显着。

因此,只需将编译标志从 -m32 更改为 -m64

,您就可以有效地从五个或六个 32 位寄存器变为 13 或 14 个 64 位寄存器

除非您有特定需要在较旧的 32 位硬件或操作系统上部署,否则没有理由编译 32 位 x86 应用程序。

将代码移植到 64 位时要小心。仍然有太多程序员将指针与 intlong 混为一谈。