在 x86-64 上,32 位应用程序是不是比 64 位应用程序有性能优势?

Posted

技术标签:

【中文标题】在 x86-64 上,32 位应用程序是不是比 64 位应用程序有性能优势?【英文标题】:Are there performance advantages of 32 bit apps over 64 bit ones, on x86-64?在 x86-64 上,32 位应用程序是否比 64 位应用程序有性能优势? 【发布时间】:2021-12-19 11:39:08 【问题描述】:

我知道 64 位相对于 32 位的优势,但除了兼容性之外,32 位应用程序相对于 64 位应用程序是否有任何优势可以使 32 位应用程序更快或更高效?

【问题讨论】:

【参考方案1】:

简而言之,没有。更准确地说,理论上某些处理器可能是这种情况,但我不知道。

我想到的唯一其他区别是 32 位指令通常更小(至少由于没有 REX 前缀),因此您可以通过这种方式节省一些空间,但它可能不会超过x64 的好处。考虑到 x64 特有的指令也往往具有更高的影响,即一次处理更多数据,代码甚至可能在 x64 中变得更紧凑。而且,出于同样的原因,x32 通常更慢。所以不,除了兼容性之外,x32 与 x64 相比没有任何真正的优势。

【讨论】:

如果你有很多指针密集的数据结构,比如树,最好的情况是 x86-64 的 ILP32 ABI(64 位模式下的 32 位指针,如 Linux's x32 ABI),因为您的数据结构的缓存占用空间比普通的 64 位 ABI 更小。在这种情况下,32 位模式可以比常规的 64 位代码更快,尽管寄存器更少并且有传统的调用约定,只要您不需要超过 4 GiB 的地址空间。对于复制大量数据,您可以在任一模式下使用 SIMD(SSE 或 AVX),每个插入 16 或 32 个字节。 也就是说,大多数程序在 64 位模式下速度更快,特别是如果他们不天真地使用 64 位整数来处理他们不需要的事情。现代 CPU 可以很好地处理 x86-64 机器码的较大平均指令大小。【参考方案2】:

有一个很大的优势:32 位应用程序使用的内存要少得多(正是因为指针更小)。并非一切都是指针,例如字符串和数字不会改变它们的大小,因此有效差异不是 2 倍。我碰巧特别了解 javascript 引擎,对于相同的工作负载,64 位版本通常比同一引擎的 32 位版本多使用大约 50% 的内存。

V8 最近通过在其 64 位版本中实现“pointer compression”解决了这个问题。理论上,任何 C/C++ 应用程序都可以做同样的事情,但这是一项巨大的工程工作。

也就是说,这通常不是不迁移到 64 位的理由,因为其他好处(更多寄存器、更多地址空间)通常会超过这个缺点。但这确实意味着,如果您的目标是内存小于 4GiB 的设备/机器,您可能希望坚持使用 32 位构建,如果内存消耗是一个问题。

(根据我的经验,性能好坏参半:更小的代码和更小的数据意味着 32 位上的缓存利用率更高;OTOH 在 64 位上拥有更多和更宽的寄存器可以在那里节省指令。在极少数极端情况下,a 64 位应用程序可以同时处理两倍的数据;大多数情况下,差异只会在 1-5% 的范围内,并且可以朝任一方向发展:有时 32-位构建确实比 64 位构建快一点;这实际上取决于应用程序在做什么。)

【讨论】:

实际上,根据我看到的一些基准,32 位代码通常有更多的缓存未命中,因为需要更多的内存访问。 64 位代码有更多寄存器,因此不需要大量溢出到内存【参考方案3】:

对于 Windows 应用程序,32 位被视为“最便携”(更易于分发),尽管这已不再是问题。

对于像 Ruby 这样的内存占用者,在我看来它使用了 1/2 的 RAM,因此您可以在 RAM 有限的机器上运行更多应用程序。更不用说“所有应用程序”使用更少的 RAM(内核等)

它的运行速度也更快,因为它遍历所有内存进行垃圾收集,这更适合缓存,需要遍历的整体 RAM 更少,寻找指针等。同时,64 位不太可能在 GC 寻找指针时发现误报,所以对于 64 位来说,胜利很小。

如果您真的很勇敢,您可以尝试混合 x32 ABI(32 位指针,64 位寄存器)https://unix.stackexchange.com/questions/121424/linux-and-x32-abi-how-to-use,它旨在实现两全其美。我真的不确定为什么它不被认为是更受欢迎的选择,这对我来说似乎是一个不错的胜利,权衡是你不能拥有超过 2GB 的 RAM。我的猜测是大多数人不是在一个非常受 RAM 限制的环境中,或者只是直接使用“32 位内核”(得到很好的支持)的胜利还不够动力?从本质上讲,大多数盒子都有大量 RAM,所以它不是那么重要?

【讨论】:

IIUC x32 的问题在于,将软件移植到它上比人们最初希望的要多得多,并且考虑到 (1) 目标受众,(2) x86 或 x64 的优势,以及 ( 3) 由于内存限制较高,大多数人会更喜欢 x64 的时间窗口都相对较小,这是不值得的。 @jmrk:如果大多数东西已经安全地编译为 32 位模式,大多数东西都可以直接编译为 x32 而不需要额外的工作;人们需要安装第三组库,以获得通常很小的性能优势,这确实是采用的阻碍。只有少数东西,如带有 JIT 引擎的 JVM 或 JS 实现需要特殊的移植工作。 x32 类型大小与 32 位模式相同,只有 long long 是 64 位类型。可能结构布局规则有些不同,比如 alignof(long long) 和 alignof(double) 可能是 8 而不是 32 位模式的 4。 x32 个用户空间进程每个可以使用 4GiB 的 RAM,而不仅仅是 2 个。与 64 位内核下的 32 位进程相同。 (它是决定计算机可以利用多少总 物理 RAM 的内核,而 x32 只是一个用户空间 ABI;内核本身总是完全 64 位的。) @PeterCordes:当然;人们希望“大多数”东西可以被编译,但实际观察是,大量的包确实需要(显着的)改编。需要第三组库这一事实是一种结果:假设,一个人可能拥有纯 x32 系统,但这并不成功,因为有太多软件在编译为时不能“正常工作” x32(或者是封闭源代码,因此不能重新编译)。

以上是关于在 x86-64 上,32 位应用程序是不是比 64 位应用程序有性能优势?的主要内容,如果未能解决你的问题,请参考以下文章

在 x86-64 中访问 32 位整数数组是不是存在性能损失?

如果 x86-64 中没有兼容模式开关,我是不是保证不会遇到非 64 位指令?

为啥 32 位寄存器上的 x86-64 指令会将完整 64 位寄存器的上部归零?

为什么Windows 32位称为Windows x86而不是Windows x32?

x86 32位操作码,x86-x64不同或完全删除

汇编语言-X86处理器架构-64位x86处理器