在 x86-64 上,32 位应用程序是否比 64 位应用程序有性能优势?
Are there performance advantages of 32 bit apps over 64 bit ones, on x86-64?
我知道 64 位相对于 32 位的优势,但除了兼容性,32 位应用程序相对于 64 位应用程序是否有任何优势可以使 32 位应用程序更快或更高效?
简而言之,没有。更准确地说,理论上某些处理器可能是这种情况,但我知道 none。
我想到的唯一其他区别是 32 位指令通常更小(至少由于没有 REX 前缀),因此您可以通过这种方式节省一些 space,但是它可能不会超过 x64 的好处。考虑到 x64 独有的指令也往往会产生更大的影响,即一次处理更多数据,代码甚至可能在 x64 中变得更紧凑。而且,出于同样的原因,x32 通常更慢。所以不,除了兼容性之外,x32 与 x64 相比没有任何真正的优势。
有一个很大的优势:32 位应用程序使用的内存少得多(正是因为指针更小)。并非一切都是指针,例如字符串和数字不会改变它们的大小,因此有效差异不是 2 倍。我碰巧特别了解 JavaScript 引擎,对于相同的工作负载,64 位版本通常比同一引擎的 32 位版本多使用大约 50% 的内存。
V8 最近通过在其 64 位版本中实现“pointer compression”解决了这个问题。理论上,任何 C/C++ 应用程序都可以做同样的事情,但这是一项巨大的工程工作。
也就是说,这通常不是不迁移到 64 位的理由,因为其他好处(更多寄存器、更多地址 space)通常会超过这个缺点。但这确实意味着如果您的目标 devices/machines 无论如何都小于 4GiB 内存,如果内存消耗是一个问题,您可能希望坚持使用 32 位构建。
(根据我的经验,性能好坏参半:更小的代码和更小的数据意味着 32 位上的缓存利用率更高;OTOH 在 64 位上拥有更多更宽的寄存器可以在那里保存指令。在极少数极端情况下,一个 64 位应用程序可以同时处理两倍的数据;大多数时候差异只会在 1-5% 的范围内,并且可以向任一方向发展:有时 32 位构建确实比 64 位构建快一点;这实际上取决于应用程序在做什么。)
对于 windows 应用程序,32 位被视为“最便携”(更易于分发),尽管这已不再是一个问题。
对于像 Ruby 这样的内存大户,在我看来它使用了 1/2 的 RAM,因此您可以 运行 在 RAM 有限的盒子上使用更多应用程序。更不用说“所有应用程序”使用更少的 RAM(内核等)
它也 运行 更快,因为它遍历所有内存进行垃圾收集,更适合缓存,需要遍历、查找指针等的整体 RAM 更少。同时,当 GC 正在寻找指针时,64 位不太可能发现误报,因此 64 位在那里小胜。
如果您真的很勇敢,可以尝试混合 x32 ABI(32 位指针,64 位寄存器)https://unix.stackexchange.com/questions/121424/linux-and-x32-abi-how-to-use,这意味着两全其美。我真的不确定为什么它不被认为是更受欢迎的选择,对我来说这似乎是一个不错的胜利,权衡是你不能拥有超过 2GB 的 RAM。我的猜测是大多数人并没有处于 RAM 非常受限的环境中,或者直接“32 位内核”(得到很好的支持)的胜利是不够的动力?本质上,大多数盒子都有大量的 RAM,所以它不是那么重要?
我知道 64 位相对于 32 位的优势,但除了兼容性,32 位应用程序相对于 64 位应用程序是否有任何优势可以使 32 位应用程序更快或更高效?
简而言之,没有。更准确地说,理论上某些处理器可能是这种情况,但我知道 none。
我想到的唯一其他区别是 32 位指令通常更小(至少由于没有 REX 前缀),因此您可以通过这种方式节省一些 space,但是它可能不会超过 x64 的好处。考虑到 x64 独有的指令也往往会产生更大的影响,即一次处理更多数据,代码甚至可能在 x64 中变得更紧凑。而且,出于同样的原因,x32 通常更慢。所以不,除了兼容性之外,x32 与 x64 相比没有任何真正的优势。
有一个很大的优势:32 位应用程序使用的内存少得多(正是因为指针更小)。并非一切都是指针,例如字符串和数字不会改变它们的大小,因此有效差异不是 2 倍。我碰巧特别了解 JavaScript 引擎,对于相同的工作负载,64 位版本通常比同一引擎的 32 位版本多使用大约 50% 的内存。
V8 最近通过在其 64 位版本中实现“pointer compression”解决了这个问题。理论上,任何 C/C++ 应用程序都可以做同样的事情,但这是一项巨大的工程工作。
也就是说,这通常不是不迁移到 64 位的理由,因为其他好处(更多寄存器、更多地址 space)通常会超过这个缺点。但这确实意味着如果您的目标 devices/machines 无论如何都小于 4GiB 内存,如果内存消耗是一个问题,您可能希望坚持使用 32 位构建。
(根据我的经验,性能好坏参半:更小的代码和更小的数据意味着 32 位上的缓存利用率更高;OTOH 在 64 位上拥有更多更宽的寄存器可以在那里保存指令。在极少数极端情况下,一个 64 位应用程序可以同时处理两倍的数据;大多数时候差异只会在 1-5% 的范围内,并且可以向任一方向发展:有时 32 位构建确实比 64 位构建快一点;这实际上取决于应用程序在做什么。)
对于 windows 应用程序,32 位被视为“最便携”(更易于分发),尽管这已不再是一个问题。
对于像 Ruby 这样的内存大户,在我看来它使用了 1/2 的 RAM,因此您可以 运行 在 RAM 有限的盒子上使用更多应用程序。更不用说“所有应用程序”使用更少的 RAM(内核等)
它也 运行 更快,因为它遍历所有内存进行垃圾收集,更适合缓存,需要遍历、查找指针等的整体 RAM 更少。同时,当 GC 正在寻找指针时,64 位不太可能发现误报,因此 64 位在那里小胜。
如果您真的很勇敢,可以尝试混合 x32 ABI(32 位指针,64 位寄存器)https://unix.stackexchange.com/questions/121424/linux-and-x32-abi-how-to-use,这意味着两全其美。我真的不确定为什么它不被认为是更受欢迎的选择,对我来说这似乎是一个不错的胜利,权衡是你不能拥有超过 2GB 的 RAM。我的猜测是大多数人并没有处于 RAM 非常受限的环境中,或者直接“32 位内核”(得到很好的支持)的胜利是不够的动力?本质上,大多数盒子都有大量的 RAM,所以它不是那么重要?