将 32 位 C++ 代码移植到 64 位 - 值得吗?为啥?
Posted
技术标签:
【中文标题】将 32 位 C++ 代码移植到 64 位 - 值得吗?为啥?【英文标题】:Porting 32 bit C++ code to 64 bit - is it worth it? Why?将 32 位 C++ 代码移植到 64 位 - 值得吗?为什么? 【发布时间】:2010-12-01 14:02:48 【问题描述】:我知道 x64 架构的一些明显优势(更高的可寻址 RAM 地址等)...但是:
如果我的程序没有真正需要在本机 64 位模式下运行怎么办。我还是应该移植它吗? 结束 32 位支持是否有任何可预见的截止日期? 我的应用程序会像原生 x64 代码一样运行得更快/更好/更安全吗?【问题讨论】:
如果做起来很简单(只需重新编译你的 C++ 代码),那就太好了。 我已经将许多应用程序移植到 x64(例如我的 shell 扩展),对于不需要它的应用程序来说,它的价值是有问题的。对于大多数应用程序(我曾经移植过的每一个),它并不像重新编译那么简单。 @NTDLS,您在移植到 x64 时遇到了哪些具体问题?如果您遇到重大问题,则可能是原始设计不太好(例如,有太多特定于架构的假设和/或 hack)。 什么操作系统?如果是 Windows,那么许多用户将无法运行您的应用程序,因为大多数用户没有 64 位 Windows。如果是 OS X,那就继续吧;今天的 OS X 已经混合了 32 位和 64 位。 我估计体面的 32 位支持将持续到 2025 年。它可能不会被放弃,直到 2038 年离舒适太近了。 【参考方案1】:除非您需要极端的安全措施或大量的 RAM,否则您不太可能看到任何好处。
基本上,您很可能直观地知道您的代码是否适合 64 位移植。
【讨论】:
【参考方案2】:这取决于您的代码是应用程序还是可重用库。对于库,请记住,该库的客户端可能有充分的理由在 64 位模式下运行,因此您必须确保您的方案有效。这也可能适用于可通过插件扩展的应用程序。
【讨论】:
【参考方案3】:关于截止日期。我不会担心,像 32 位这样的东西会在本地存在一段时间,并且在可预见的未来会以其他形式存在。
【讨论】:
【参考方案4】:查看我对这个问题的回答here. 我关闭了那个帖子,说 64 位计算机可以存储和检索比 32 位计算机更多的信息。对于大多数用户而言,这实际上并不意味着太多,因为诸如浏览网页、查看电子邮件和玩纸牌游戏之类的事情都可以在 32 位寻址的范围内轻松运行。 64 位优势真正发挥作用的地方在于您拥有大量计算机必须处理的数据。数字信号处理、十亿像素摄影和高级 3D 游戏都是在 64 位环境中大幅提升其海量数据处理能力的领域。
至于您的代码运行得更快/更好,这完全取决于您的代码和对其施加的要求。
【讨论】:
【参考方案5】:如果您现在没有任何实际需求,并且可能永远不会,那么对于 64 位模式,您不应该进行移植。
如果您现在不需要,但有一天可能需要,您应该尝试估计需要付出多少努力(例如,通过打开所有相应的编译器警告,并尝试 64 位编译)。预计有些事情并非微不足道,因此了解您可能会遇到哪些问题以及解决这些问题可能需要多长时间会很有用。
请注意,依赖项也可能产生需求:如果您的程序是库(例如 DLL),则可能需要将其移植到 64 位模式,因为某些主机应用程序被移植。
在可预见的未来,将继续支持 32 位应用程序。
【讨论】:
【参考方案6】:以下是 64 位的功能:
64 位允许您使用比 32 位应用程序更多的内存。 64 位使所有指针均为 64 位,这使您的代码占用空间更大。 64 位为您提供更多整数和浮点寄存器,从而减少向内存溢出的寄存器,这应该会在一定程度上加快您的应用程序的速度。 64 位可以使 64 位 ALU 运算更快(仅当您使用 64 位数据类型时才有用)。 您不会获得任何额外的安全性(另一个答案提到了安全性,我不知道有这样的好处)。 您只能在 64 位操作系统上运行。我已经移植了许多 C++ 应用程序,并且看到使用 64 位代码(相同的系统、相同的编译器,唯一的变化是 32 位和 64 位编译器模式)的速度提高了大约 10%,但大多数这些应用程序进行了大量的 64 位数学运算。 YMMV。
我不会担心 32 位支持很快就会消失。
(已编辑以包含来自 cmets 的注释 - 谢谢!)
【讨论】:
您忘记了 x86 处理器在 64 位模式下提供的寄存器比在 32 位模式下多得多。这允许编译器优化您的代码以将更多内容保存在寄存器中而不是内存中。 你没有提到平面分割。如果出于某种原因您想要使用分段,则不能使用 64 位代码。 如果您使用地址空间布局随机化,您可以在 64 位模式下获得额外的安全性。 32 位地址空间足够小,有时可以通过蛮力破解。 64 位空间并非如此。 由于 x86_64 中已经存在 NX 位,这在以前的 x86 CPU 中可能不存在,因此您也获得了一些更安全的信息。 Windows 64 位还需要对驱动程序进行签名,使其更加稳定和安全。此外,64位并不一定会使占用空间更大,因为有x32 ABI其中的指针仍然是32位en.wikipedia.org/wiki/X32_ABI【参考方案7】:-
如果您的程序不需要在 64 位下运行,您为什么要这样做?如果您不受内存限制,并且您没有庞大的数据集,那就没有意义了。新的 Miata 没有更大的轮胎,因为它不需要它们。
32 位支持(即使仅通过仿真)将在您的软件不再有用时延长很久。我们仍然在模仿 Atari 2600,对吧?
不,很可能,您的应用程序在 64 位模式下会变慢,这仅仅是因为处理器缓存中容纳的应用程序较少。它可能更安全一些,但优秀的编码人员不需要那个拐杖:)
Rico Mariani 关于为什么微软不将 Visual Studio 移植到 64 位的帖子确实总结了 Visual Studio: Why is there no 64 bit version? (yet)
【讨论】:
感谢 64 位 Visual Studio 链接 - 我不知道。非常酷的帖子! 你应该小心,以免你挑选一些产品来支持你的观点。是的,没有 64 位 VS2010(这并不意味着它不会被考虑用于某些未来的版本),但另一方面,Office 2010 将有一个 64 位版本,这是一个更受欢迎的应用程序 - 并且还有一个没有明确需要是 64 位的。 @Pavel 否则您将如何加载 5GB Excel 电子表格? :D 64 位 VS 将会出现。 3rd 方加载项肯定是一个/关键障碍,而且是合理的。 @mctrousers 任何使用 5GB Excel 电子表格的人显然都在使用错误的工具来完成这项工作。您究竟会在这么大的电子表格中存储什么,并且不会更适合数据库?但是要回答您的问题,您可以通过不一次将整个内容全部加载到内存中来做到这一点。【参考方案8】:x86-64 有点特殊——对于许多架构(例如 SPARC),为 64 位模式编译应用程序不会给它带来任何好处,除非它可以有利地使用超过 4GB 的内存。它所做的只是增加二进制文件的大小,如果它影响缓存行为,实际上会使代码变慢。
但是,x86-64 不仅为您提供了 64 位地址空间和 64 位整数寄存器 - 它还使通用寄存器的数量加倍,这在像 x86 这样的寄存器不足架构上只需重新编译即可显着提高性能。
它还让编译器假设存在许多扩展,例如 SSE 和 SSE2,这也可以显着改进代码优化。
另一个好处是 x86-64 增加了 PC 相对寻址,可以显着简化与位置无关的代码。
但是,如果应用对性能不敏感,那么这些都不是很重要。
【讨论】:
严格来说,x86-64 并不一定是真实寄存器数量的两倍。我相信所有桌面 CPU 都在执行管道中进行寄存器重命名,所以 x86-64 的所有变化都是架构上可见的寄存器数量,而不是实际数量。现在,这可以让编译器有更多的能力来消除加载和存储操作,因此可以使用额外的架构寄存器来启用代码提升等优化。 使这些寄存器对编译器可见肯定有助于它优化 - 一般来说,可以在更高层进行的优化越多越好。 除了增加二进制文件的大小外,它还会使每次使用的指针大小增加一倍,但其性能影响可能归结为您确实注意到的“缓存行为”。 一个很好的答案,你指出了所有重要的主要区别(或缺乏)。只要我愿意比较架构,我就一直对扩展假设赞不绝口。 :) 此外,x86-64 添加了 PC 相对寻址,这有助于 PIC 代码。【参考方案9】:您已经意识到 x64 的优势(最重要的是增加的 RAM 大小)并且您对任何内容都不感兴趣,那么就不要移植可执行文件 (exe)。通常移植后性能会下降,主要是由于 x64 模块的大小比 x86 增加:所有指针现在都需要双倍长度,这会渗透到任何地方,包括代码大小(一些跳转、函数调用、vtables、虚拟调用、全局符号等等等等)。不是明显的降级,但通常是可测量的(速度降低 3-5%,取决于许多因素)。
DLL 值得移植,因为您在能够使用您的 DLL 的 x64 应用中获得了新的“受众”。
【讨论】:
大约是时候有人提到“观众”了!似乎很多消费者都在为他们的机器寻找 64 位应用程序。【参考方案10】:我还没有看到提到的一个可能的好处是它可能会发现潜在的错误。一旦将其移植到 64 位,就会进行许多更改。某些数据类型的大小发生了变化,调用约定发生了变化,异常处理机制(至少在 Windows 上)发生了变化。
所有这些都可能导致隐藏的错误浮出水面,这意味着您可以修复它们。
假设您的代码正确且没有错误,理论上移植到 64 位应该像轻按编译器开关一样简单。如果失败,那是因为您依赖于语言无法保证的东西,因此它们是潜在的错误来源。
【讨论】:
好点。除其他外,在架构和编译器切换期间会出现许多错误。 同意。我在尽可能多的不同平台上使用尽可能多的不同编译器编译我的代码。你能以这种方式找到的东西真是太棒了。 嗯,这也是一个缺点:我希望你会自己发现自己新出现的错误,否则你会遇到一些安全漏洞!【参考方案11】:虽然 32 位确实会以某种形式出现一段时间,但 Windows Server 2008 R2 仅附带 64 位 SKU。随着更多软件迁移到 64 位,早在 Windows 8 中看到 WOW64 作为安装选项,我不会感到惊讶。 WOW64 是安装、内存和性能开销。 32 位 Windows 中的 3.5GB RAM 限制以及不断增加的 RAM 密度将鼓励这种迁移。我宁愿拥有更多的内存而不是 CPU...
拥抱 64 位!花点时间让您的 32 位代码兼容 64 位,这很简单,也很简单。对于正常应用程序,更改更准确地描述为代码更正。对于司机来说,选择是:适应或失去用户。时机成熟时,您可以通过重新编译在任何平台上进行部署。
IMO 目前缓存相关问题尚无定论;这方面的芯片改进和进一步的 64 位优化即将推出。
【讨论】:
您知道 32 位版本的 Win7 仍然可以运行 16 位应用程序,是吗?所以我认为现在谈论取消 32 位支持还为时过早。 为什么微软已经在 Server 2008 R2 中做到这一点还为时过早? 16 位支持不是本机的,32 位支持不一定是本机的; Windows 7 的 XP Mode 已经指向了一个可能的方向。准备成本很低 服务器操作系统是一个特例。服务器需要做很多工作,并且会使用所有可用的资源来完成这项工作。 64 位无疑为那里的性能提供了很大的改进。对于通用的东西,64 位没有任何优势。除非有特定原因要迁移到 64 位,否则不要这样做。这太浪费时间了,最好把时间花在添加功能和修复错误上。 也是这样工作的,64位操作系统支持Wow32,但不支持Wow16,32位操作系统支持Wow16。因此,如果 128 位机器出现,那么 wow32 很可能会被踢到路边。【参考方案12】:除非出于商业原因转向 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 高得多。【参考方案13】:例如,如果您编写了 32 位代码 (GNU C/++),如下所示 编辑:格式代码
struct packet
unsigned long name_id;
unsigned short age;
;
对于网络消息,那么你需要在 64 位系统上重新编译时进行移植,因为 htonl/ntohl 等,在网络对等体仍在使用 32 位系统的情况下通信会中断(使用与您的代码相同);你知道 sizeof(long) 也会在你身边从 32 变成 64。
在http://code.google.com/p/effocore/downloads/list,文档名称 EffoCoreRef.pdf 上查看有关 32/64 移植的更多说明。
【讨论】:
我使用的是 64 位系统,速度更快,内存更多;很不错。 也可以参考code.google.com/p/effogpled/downloads/list,文档名为EffoDesign_MemTest.pdf,了解最新x86_64平台上的多通道MC和并发数据总线突发等。【参考方案14】:某些操作系统或配置无法运行 32 位程序。例如,没有安装 32 位 libc 的最小 Linux。另外 IIRC 我通常会从内核编译出 32 位支持。
如果这些操作系统或配置是您潜在用户群的一部分,那么是的,您应该移植它。
如果你需要更快的速度,那么你也应该移植它(正如其他人所说,x86-64 有更多的寄存器和很酷的指令可以加快速度)。
或者,当然,如果您想要 mmap() 或以其他方式映射大文件或大量内存。那么 64 位会有所帮助。
【讨论】:
【参考方案15】:至于性能问题,实际上取决于您的程序。如果你的程序是指针密集型的,移植到 64 位可能会导致性能下降,因为对于相同大小的 CPU 缓存,每个 64 位指针在缓存上占用更多空间,虚拟到物理映射也占用更多 TLB 空间.否则,如果您的程序不是指针密集型的,它的性能将受益于 x64。
当然性能不是移植的唯一原因,还应考虑移植工作量、时间安排等其他问题。
【讨论】:
【参考方案16】:我建议将其移植到 64 位,以便您运行“本机”(另外,我使用 OpenBSD。在他们的 AMD64 端口中,他们不提供任何 32 位仿真支持,一切都必须是 64 位)
另外,stdint.h
是你最好的朋友!通过移植您的应用程序,您应该学习如何可移植地编写代码。当我们也有 128 位处理器时,这将使您的代码正常工作(希望在几十年内)
我已经将 2 或 3 个东西移植到 64 位,现在为两者开发(如果您使用 stdint.h,这很容易),并且在我的第一个项目移植到 64 位时,会出现 2 或 3 个错误,但就是这样。其中大部分是一个简单的重新编译,现在我在编写新代码时不用担心 32 位和 64 位之间的差异,因为我只是自动可移植地编写代码。 (使用 intptr_t 和 size_t 等)
【讨论】:
【参考方案17】:如果从 64 位进程调用 dll,则 dll 也必须是 64 位。 那么值不值也没关系,你根本就别无选择。
【讨论】:
【参考方案18】:要记住的一个问题是可用的软件库。例如,我的公司开发了一个使用多个 OpenGL 库的应用程序,我们在 OpenSuSE 操作系统上这样做。在旧版本的操作系统中,可以在 x86_64 架构上下载这些库的 32 位版本。然而,较新的版本没有这个。它使在 64 位模式下编译变得更容易。
【讨论】:
【参考方案19】:64位会跑的快很多,等64位编译器成熟了,不知道什么时候出现
【讨论】:
以上是关于将 32 位 C++ 代码移植到 64 位 - 值得吗?为啥?的主要内容,如果未能解决你的问题,请参考以下文章