将Windows应用程序编译为64位是否真的有意义?

24

我可以自信地说,我们编写的99%应用程序不需要处理超过2GB的内存。当然,64位的操作系统可以更好地管理更多的内存,但是一个典型的应用程序被编译成64位是否有任何特定原因呢?


3
因为同样的原因,你是否仍在运行16位应用程序? - Patrick
9
那是一个愚蠢的比较。16位应用程序出问题的原因有很多。需要的内存分段更加麻烦,内存限制也远远更低。此外,16位整数的能力要受到很大的限制。 - Mr. Boy
3
32位应用程序可以分配(和寻址)超过2GB的内存。但是你无法同时将所有内存映射到你的地址空间中:http://blogs.msdn.com/oldnewthing/archive/2009/07/06/9818299.aspx - Bill
1
不是这样的,John。这不是一个分段问题——操作系统可以简单地为您保留一块未映射到您的地址空间中的内存块。这里没有类似近指针和远指针的情况,因为即使是远指针也仍然可以看到它的所有数据。如果取消映射数据,则必须将其重新映射回您的地址空间,然后才能看到其中的任何内容。它也不是使用指针进行管理,但那是另一个话题...。 - Billy ONeal
@MSalters, 如果你链接的时候带有LARGEADDRESSAWARE标志,并且使用/3GB标志启动XP(不确定Vista或W7),你可以寻址3GB。如果你在64位Windows系统上运行LARGEADDRESSAWARE应用程序,甚至可以使用4GB的可寻址虚拟内存。 - Patrick
显示剩余3条评论
12个回答

20

64位系统可能会有性能提升。一个很好的例子是函数调用中的一些参数通过寄存器传递(少了在堆栈中需要推送的东西)。

编辑 我查阅了一些我以前学习我们产品在64位版本和32位版本下运行差异时的笔记。我在一台四核64位机器上运行了测试。所以比较起来就好比比较苹果和橙子,因为32位版本显然是在模拟模式下运行的。然而,许多我读到的文章(例如这篇文章)一直说WOW64的速度损失并不显著。但即使这句话不是真的,在一个64位操作系统上几乎肯定会运行您的应用程序。因此,在64位机器上比较32位版本和64位版本具有价值。

在我进行的测试中(当然不是全面的),我没有发现32位版本更快的情况。然而,我运行的许多SQL密集型操作(高CPU和高I/O)在使用64位版本时要快20%到50%。这些测试涉及到一些相当“丑陋”的SQL语句以及一些高并发的TPCC测试。当然,很多东西都取决于编译器开关,所以你需要自己进行测试。


7
也值得一提的是,32位应用程序在模拟器(WOW64)上运行。 - Chris Shaffer
但是同样存在潜在的负面性能问题,不是吗?我印象中差异非常微小。而且它真的是一个“模拟器”吗? - Mr. Boy
5
请注意,“模拟器”在硬件上得到支持,不像真正的模拟器那样会带来传统的性能损失。但是,您需要支付抽象调用路径和注册表函数的代价。但感谢您指出这一点。 - Billy ONeal
@John:在我对我们产品的测试中,我没有发现任何比较慢的地方(也许是因为我测试的不够全面)。相当多的不同操作速度都更快了(因为这是一个数据库服务器)。当我回到工作岗位时,我会找出数据的,但如果我没记错,速度通常比原来快10%或更多。这并不仅仅是模拟器与非模拟器之间的差别。 - Mark Wilkins
64位代码可能会更大,而且指针存储的要求肯定更高。因此,内存带宽和缓存利用率会受到一些影响。 - Mark Ransom
当然,它是在模拟器下运行的,但这就是问题的关键。当你考虑到处理器本身具有执行本地代码的模式时,将其称为模拟器就有些牵强了。 - Tyler

14

现在就将它们构建为64位,即使您永远不会发布该版本,也可以帮助您找到并修复在以后被迫构建和发布64位版本时可能遇到的问题。


为什么我被迫发布64位版本? - Mr. Boy
5
现在你无法确定这一点。32位CPU可能会像16位CPU一样被淘汰,只用于嵌入式角色;这是不可预测的。 - Ignacio Vazquez-Abrams
4
@John: 16位应用程序无法在64位Windows操作系统上运行。绝对不行。 - Billy ONeal
4
@John:实际上这是x86硬件问题。16位软件在“虚拟8086”模式下运行。当处理器本身处于32位模式时,这很容易实现。然而,当x86-64处理器本身处于64位模式时,它只能运行64位和32位应用程序(长模式/兼容模式)。 - MSalters
1
当客户要求能够访问超过4GB的数据时,你会被“迫”发布64位版本。即使在可预见的未来不太可能发生,最好还是为此做好准备。 - Gabe
显示剩余4条评论

10

x64有八个额外的通用寄存器,在运行32位代码时不可用。相当于三倍的数量(如果将ESI、EDI、EBP和ESP视为通用寄存器,则为两倍;我不这样认为)。在使用超过四个变量的函数中,这可以节省许多加载和存储操作。


10

不要低估提供本地64位版本产品的市场价值。

另外,你可能会惊讶于有多少人在开发需要尽可能多内存的应用程序。


1
当苹果推出英特尔Mac时,同样的效果非常明显。如果你的应用程序不是通用二进制文件,则相当大一部分Mac用户群体将不会使用它。 - the_mandrill

6

如果你需要超过2GB的内存,那么我建议你使用64位编译。但需要注意的是,64位编译意味着64位指针,这意味着代码和数据结构会变得更大,导致应用程序从缓存中受益较少,并且会更频繁地访问虚拟内存等。

因此,如果你不需要它,基本上会使你的应用程序变慢并且更加臃肿,没有必要。

尽管如此,随着时间的推移,你将更关心64位,因为所有工具和库等都将为其编写。即使你的应用程序可以在64K中良好运行,你也不太可能使用16位代码——收益并不重要(它已经是一个小而快速的应用程序),而且肯定会被麻烦所困扰。随着时间的推移,我们也会看到32位的情况类似。


5
您可以考虑它作为未来的保障。虽然这可能还有很长的路要走,但请考虑一下未来几年,当64位操作系统和CPU普及时(就像16位在32位取代后消失了一样)。如果您的应用程序是32位的,而您的所有竞争对手都已经转向64位,那么您的应用程序可能会被视为过时、速度较慢或无法改变(甚至有一天,对32位应用程序的支持也可能被停止或不完整,例如Windows 7是否可以正确运行16位应用程序?)。如果您今天已经构建了一个64位版本的应用程序,那么您就可以避免这些问题。如果您推迟到以后再进行移植,那么您可能会在现在和移植之间编写更多的代码,那么移植就会更加困难。
对于许多应用程序来说,并没有太多引人注目的技术原因,但如果轻松实现移植,现在移植可能会为您节省未来的努力。

1

如果您不需要扩展地址空间,以64位模式交付将毫无意义,并且会带来一些缺点,例如增加内存消耗和缓存压力。

虽然我们提供64位版本,但我们的客户已经达到极限,他们正在推动我们减少内存消耗,以便获得这些优势。


1

所有可能需要大量内存的应用程序:希望在内存中缓存大量数据的数据库服务器,处理大量数据的科学应用程序,...


没错。它们属于不“正常”的1%应用之一。我们这里很少有人在编写数据库服务器。 - Mr. Boy
我正在编写科学模拟软件,有时需要加载和处理数据库中数百万的记录。越来越多的情况下,2GB的限制真的成为了一个问题。对于我来说,64位已经变得必不可少。 - Patrick

1

我最近读了这篇文章,优化C++软件。在第2.3章节“操作系统的选择”中,对64位和32位系统的优缺点进行了比较,并提出了一些关于Windows的具体观察。

Mark Wilkins已经在本主题中指出了函数调用更多寄存器的问题。64位系统的另一个有趣特性是:

SSE2指令集在所有64位CPU和操作系统上都得到支持。

SSE2指令可以提供出色的优化效果,并且它们正在越来越广泛地使用,因此我认为这是一个值得注意的特性。


是的,但SSE1/2/3仍可通过32位应用程序访问。因此,您所获得的只是一些一致性,即知道您的代码目标PC都将具有SSE2? - Mr. Boy
是的,我可能应该说现代大多数32位系统现在都支持SSE。 64位系统只是保证可用性。 - fogo

0

Fastcall通过将前四个参数保存在寄存器中,使调用子程序更快。


有时候——并非总是如此。由于fastcall,某些函数调用会得到一些改进,但它会强制在被调用的函数内部存储寄存器的当前状态。 - Billy ONeal
它们可以保存到寄存器中,或者在最坏的情况下,保存到堆栈中。 - Jens Björnhager

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