将32位C++代码移植到64位——是否值得?为什么?

45

我知道x64架构的一些明显优点(更高可寻址的RAM地址等)……但是:

  • 如果我的程序没有真正需要在本机64位模式下运行,我还应该移植它吗?
  • 是否有预期的截止日期来结束32位支持?
  • 作为本机x64代码,我的应用程序是否会更快/更好/更安全地运行?

1
如果很简单(只需重新编译您的C++代码)就去做吧,这很好。 - toto
1
我已经将许多应用程序移植到x64(例如我的shell扩展),对于不需要它的应用程序来说,这是值得考虑的问题。对于大多数应用程序(我曾经移植过的每一个应用程序),它并不像简单的重新编译那样简单。 - NTDLS
7
@NTDLS,你在将代码移植到x64架构时遇到了哪些具体问题?如果你遇到了重大困难,那么可能原始设计并不是很好(比如有太多特定于架构的假设和/或技巧)。 - Pavel Minaev
1
我估计良好的32位支持将持续到2025年。直到2038年接近时才可能被废弃,这样做可能会让人感到不舒服。 - Matt Joiner
@Matt,假设使用其他平台,看起来苹果公司会更早地强制执行此项要求。 - Pharaun
显示剩余2条评论
19个回答

67

x86-64有些特殊,对于许多体系架构(例如SPARC),将应用程序编译为64位模式并不会带来任何好处,除非它能够有效地使用超过4GB的内存。所有它所做的就是增加二进制文件的大小,这实际上可能会使代码变慢,如果它影响了缓存行为。

然而,x86-64不仅提供了64位地址空间和64位整数寄存器 - 它还加倍了通用寄存器的数量,在像x86这样缺乏寄存器的体系架构上,只需重新编译即可显著提高性能。

此外,它还允许编译器假定许多扩展功能,如SSE和SSE2已存在,这也可以显著改善代码优化。

另一个好处是x86-64添加了PC相对寻址(PC-relative addressing),这可以显著简化位置无关代码(position-independent code)。

但是,如果应用程序对性能不敏感,那么这一切都不是很重要。


4
严格来说,x86-64并不一定会将真实寄存器数量加倍。我相信所有的台式机CPU都在执行流水线中进行寄存器重命名,因此x86-64改变的只是体系结构可见寄存器的数量,而不是实际寄存器的数量。现在,这可以使编译器更有能力消除加载和存储操作,因此优化如代码提升可能会利用额外的体系结构寄存器。 - DigitalRoss
6
将这些寄存器对编译器可见,肯定有助于优化,通常在更高的层次上进行的优化越多越好。 - caf
2
除了增加二进制文件的大小外,它还会使每个指针使用的大小翻倍,但其性能影响可以归为“缓存行为”,这一点你已经注意到了。 - Falaina
2
此外,x86-64 添加了 PC 相关寻址,有助于 PIC 代码。 - ninjalj
需要注意的是,在Windows系统上,当您将应用程序编译为本机x64时,您不再通过WOW64子系统虚拟运行程序 - 这本身就会对性能产生影响 - 不管大小如何,至少是可测量的,并且可能取决于您的应用程序是否是CPU或I/O密集型等。 - 10100111001
显示剩余2条评论

28

可能有一个未被提及的潜在优势是它可能会发现潜在的bug。一旦将其移植到64位,就会进行许多更改。某些数据类型的大小会改变,调用约定会改变,在Windows上,异常处理机制也会改变。

所有这些都可能导致隐藏的bug浮出水面,这意味着您可以修复它们。

假设您的代码正确且无漏洞,则理论上将其移植到64位应该很简单,只需要打开编译器开关即可。如果失败了,那是因为您依赖于语言不保证的东西,因此它们是潜在的错误来源。


很好的观点。许多错误会在架构和编译器切换等过程中出现。 - Matt Joiner
1
同意。我会尽可能地使用许多不同的编译器和平台来编译我的代码。这样做可以发现很多令人惊奇的问题。 - Kristopher Johnson
5
好的,这也是一个缺点:我希望你能够发现自己新出现的漏洞,否则你最终会留下一些安全隐患! - Dacav

18

64位技术给你带来以下好处:

  • 64位让你可以使用比32位应用程序更多的内存。
  • 64位使所有指针都变成了64位,这会增加你的代码占用内存。
  • 64位提供了更多整数和浮点寄存器,减少寄存器溢出到内存的情况,从而应该加速你的应用程序。
  • 64位可以使64位ALU操作更快(只有在使用64位数据类型时才有用)。
  • 你不会获得任何额外的安全性(另一个答案提到了安全性,我没有意识到有类似的好处)。
  • 你只能在64位操作系统上运行。

我移植了许多C++应用程序,并看到64位代码提高了大约10%的速度(相同的系统、相同的编译器,唯一的变化是32位与64位编译器模式),但其中大部分应用程序都进行了相当数量的64位数学计算。个人经验因人而异。

我不会担心32位支持会很快消失。

(编辑评论中的笔记-谢谢!)


1
你忘记了x86处理器在64位模式下提供的寄存器比32位模式下多得多。这使得编译器可以优化你的代码,将更多的内容保存在寄存器中而不是内存中。 - lhahne
你没有提到平面分段。如果出于某种原因你想要使用分段,那么你不能使用64位代码。 - Nathan Fellman
4
如果你使用地址空间布局随机化,64位模式下可以获得额外的安全性。32位地址空间太小,有时可能会被暴力破解,但64位则不会。 - dsimcha
1
你也会更安全一些,因为x86_64中已经有了NX位,而在以前的x86 CPU中可能没有。Windows 64位还需要驱动程序签名,使其更加稳定和安全。此外,64位不一定会使占用空间变大,因为还有x32 ABI,其中指针仍然是32位 https://en.wikipedia.org/wiki/X32_ABI - phuclv

5
尽管32位技术在某种程度上将继续存在一段时间,但Windows Server 2008 R2仅提供64位SKU。随着越来越多的软件迁移到64位,我不会惊讶地看到WOW64成为Windows 8的安装选项。WOW64是一种安装、内存和性能开销。32位Windows中的3.5GB RAM限制以及RAM密度的增加将促进这种迁移。我宁愿拥有更多的RAM而不是CPU...
拥抱64位!花些时间使您的32位代码兼容64位,这是一个简单明了的选择。对于普通应用程序,更准确的描述是代码纠正。对于驱动程序,选择是:适应或失去用户。当时机成熟时,您将准备好在任何平台上重新编译部署。
在我看来,当前的缓存相关问题已经无足轻重;硅改进和进一步的64位优化将会出现。

您知道Win7的32位版本仍然可以运行16位应用程序,对吗?因此,我认为谈论删除32位支持还为时过早。 - jalf
1
为什么说这是过早的呢?微软在Server 2008 R2中已经完成了这项工作。16位支持不是本地支持,32位支持也不必是本地支持;Windows 7的XP模式已经指出了一个可能的方向。做好准备成本很低。 - user172783
服务器操作系统是一个特殊情况。服务器需要执行大量工作,并将使用其所有可用资源来完成该工作。64位无疑在这方面对性能提供了很大的改进。对于一般用途而言,64位不提供任何优势。除非有特定原因需要转换到64位,否则不要这样做。这是可怕的浪费时间,最好把那些时间用于添加功能和修复错误。 - CMircea
还有一个问题是,64位操作系统支持Wow32,但不支持Wow16,而32位操作系统则支持Wow16。所以如果出现128位的机器,Wow32很可能会被淘汰。 - paulm

3
  1. 如果你的程序没有必要在64位下运行,为什么要这样做呢?如果你不受内存限制,也没有大型数据集,那就没有必要了。新款Miata车没有更大的轮胎,因为它不需要。
  2. 32位支持(即使只是通过仿真)将会延续很长时间,直到你的软件不再有用为止。我们现在还在模拟Atari 2600吧?
  3. 不,很可能你的应用程序在64位模式下会变慢,因为它的一部分无法适应处理器的缓存。它可能会更加安全,但好的程序员不需要这个拐杖 :)

Rico Mariani关于为什么微软没有将Visual Studio移植到64位的帖子真正总结了一切 Visual Studio: Why is there no 64 bit version? (yet)


感谢提供64位的Visual Studio链接 - 我之前不知道。非常酷的帖子! - NTDLS
3
你应该小心,不要只挑选某些产品来支持你的观点。是的,现在没有64位的VS2010(这并不意味着将来不会考虑加入),但另一方面,Office 2010将有一个64位版本,而且它是一个更受欢迎的应用程序,也没有明显需要成为64位。 - Pavel Minaev
3
@Pavel,你还有什么其他方法可以加载一个5GB的Excel电子表格吗?:D64位的Visual Studio将会发布。第三方插件肯定是一个/关键障碍,并且这是合理的。 - user172783
@mctrousers 任何使用5GB的Excel电子表格的人显然是在错误的工具上进行操作。你会在电子表格中存储什么内容,以至于需要如此大的空间,而不是更适合数据库的存储方式呢?但是为了回答你的问题,你可以通过不一次性将整个电子表格加载到内存中来完成。 - JBentley

3
除非有商业理由需要转向64位,否则就没有真正的“必要”支持64位。
然而,除了其他人已经提到的所有好处之外,某些原因在某个时候转向64位是有好处的。
  • 越来越难买到不支持64位的PC。即使32位应用程序将在未来几年内以兼容模式运行,但今天或未来销售的任何新PC都可能是64位。如果我有一个闪亮的64位操作系统,我不想在兼容模式下运行“旧气味的32位应用程序”!

  • 有些东西在兼容模式下无法正常运行——这不同于在32位硬件上运行32位操作系统。当我在兼容模式下运行时会遇到一些问题(例如跨32/64位注册表区域访问注册表、程序因为它们不在所期望的文件夹中而失败等),我总是感到紧张。我总觉得在兼容模式下运行我的代码只是“不是真正的东西”,而且经常会出现问题。

  • 如果您编写的代码干净利落,那么很有可能只需要重新编译为64位exe,它就可以正常工作,因此没有真正的理由不尝试一下。

  • 越早构建本机64位版本,将来添加新功能时就越容易使其在64位上正常工作。这比在另外“n”年中继续在黑暗时代开发然后试图跳出光线要好得多。

  • 当您进行下一次工作面试时,您将能够说自己具有64位经验和32->64端口经验。


兼容模式是Vista和Win7 Wow64仿真器中的一件事情;但Windows 7 XP模式使用XP虚拟机,这对于99.99%的情况来说确实是真正的解决方案 - 比Wow64高得多,我同意它存在一些问题。 - Nate

2

这取决于你的代码是应用程序还是可重用库。对于一个库而言,要记住该库的客户端可能有充分的理由在64位模式下运行,因此您必须确保您的情况可以正常工作。当应用程序通过插件进行扩展时,这也可能适用。


2

如果您现在没有任何实际需要并且将来也不太可能需要64位模式,那么您就不应该进行移植。

如果您现在没有这个需求,但未来可能会有,您应该尝试估计所需的努力程度(例如,打开所有相关编译器警告并尝试进行64位编译)。请预期一些问题并非简单易解,因此了解您可能遇到的问题和解决它们需要多长时间将很有用。

请注意,需求也可能源自依赖关系:如果您的程序是一个库(例如DLL),则可能需要将其移植到64位模式,仅因为某些主机应用程序已经移植到了该模式。

在可预见的未来,32位应用程序将继续受到支持。


1
例如,如果您编写了以下32位代码(GNU C / ++) 编辑:格式化代码
struct packet {
    unsigned long name_id;
    unsigned short age;
};

对于网络消息传递,如果你在一个64位系统上重新编译时需要进行移植,因为在网络对等方仍然使用32位系统(使用与你相同的代码)的情况下,由于使用了htonl/ntohl等函数,通信会中断;你知道,在你这边,sizeof(long)也将从32位变为64位。
关于32/64位移植的更多注意事项,请参考http://code.google.com/p/effocore/downloads/list,文档名为EffoCoreRef.pdf。

1
我正在使用64位系统,速度更快,内存更大;非常不错。 - Test
您可以参考 http://code.google.com/p/effogpled/downloads/list,其中的 EffoDesign_MemTest.pdf 文档,了解最新 x86_64 平台上多通道 MC 和并发数据总线突发等内容。 - Test

1

你已经了解了x64的优势(最重要的是增加的RAM大小),并且对此不感兴趣,那么就不要移植可执行文件(exe)。通常情况下,在移植后性能会降低,主要是由于x64模块的大小增加而导致的:现在所有指针都需要双倍长度,并且这种影响会扩散到各个方面,包括代码大小(一些跳转、函数调用、虚表、虚拟调用、全局符号等等)。虽然不是很明显的降级,但通常是可以测量的(速度降低3-5%,取决于许多因素)。

DLL值得移植,因为您可以在能够使用您的DLL的x64应用程序中获得新的“受众”。


2
关于提到“受众”的事情,终于有人说了!看起来很多消费者都在寻找适用于他们机器的64位应用程序。 - NTDLS

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