是否有充分的理由在64位计算机上运行32位软件而不是64位?


56

是否有充分的理由提供针对现代台式机的任何32位版本以及64位版本的任何软件,这些台式机在64位硬件上运行现代64位操作系统?

看来64位软件会更高效,并在需要时允许更高的内存使用率,等等。Apple甚至在手机上使用64位处理器,即使它们只有1-2 GB RAM,也远低于4 GB。 32位CPU的限制。


16
并非每台现代机器都运行64位操作系统
巴林特

4
你有什么例子吗?
Filip Haglund

8
问你的顾客。
墨菲

22
修辞问题:由于大多数现代64位操作系统也允许运行32位和64位应用程序,因此是否有理由提供任何软件的64位版本?
布朗

2
不是重复的@gnat。这个问题是关于安装时间戳,以及在程序退出时返回的错误代码中的开发人员ID。
Filip Haglund

Answers:


80

在64位环境中使用32位软件的好处

  • 较低的内存占用,尤其是在指针密集型应用中,64位和32位可以轻松使内存需求翻倍。
  • 目标文件也较小。
  • 与32位环境的兼容性。
  • 内存泄漏被硬限制为2 GB,3 GB或4 GB,并且不会淹没整个系统。

64位环境中32位软件的缺点

  • 每个进程2 GB,3 GB或4 GB内存限制。(仅对于每个进程,总而言之,多个32位进程可能会使用全部可用的系统内存。)
  • 不使用其他寄存器和指令集扩展(取决于x64)。这是高度编译器和CPU特定的。
  • 可能需要所有(大多数Linux发行版)库或不常见的(大多数Windows版本)库的32位版本以及运行时环境。如果共享库的32位版本是专门为您的应用程序加载的,则这会占用您的资源。如果您进行静态链接,则没有任何区别。

其他方面

  • 驱动程序通常不是问题。只有用户空间库应该在32位和64位之间有所不同,而不是内核模块的API。
  • 注意整数数据类型的不同默认宽度,需要其他测试。
  • 64位CPU架构甚至可能根本不支持32位。
  • 在32位执行模式下,某些技术(如ASLR和其他技术)依赖于比物理内存大得多的地址空间,这些技术无法(或根本无法)正常工作。

除非在这里比较非常具体的CPU架构,操作系统和库基础结构,否则我将无法进一步详细介绍。


8
“ 64位CPU架构甚至可能根本不支持32位。” 这更多是理论上的关注,还是世界上存在?
mucaho

10
@mucaho肯定只有64位的CPU体系结构,例如Alpha和IA64。不过,这两个都是垂死的。我不知道现在是否有任何目前生产的仅64位体系结构-AArch64,也许吗?有谁知道32位ARM是否是其中的强制性组件?
zwol

10
@zwol不,ARM不要求32位,也不是64位。仅存在64位ARM CPU,而其他CPU支持32位和64位进程。
Ext3h '16

3
仅选择一种架构并坚持下去还有一个额外的好处:简化开发和测试。
jl6

7
@Joshua一直存在吗?法老知道吗?
candied_orange

7

32位软件和64位软件之间的区别在于指针的大小,也可能是整数寄存器的大小。而已。

这意味着程序中的所有指针的大小都是其两倍。而且(至少在ILP32 / LP64架构上)long的大小也是其两倍。这通常会使目标代码大小增加大约30%。这意味着 …

  • 您的目标代码将需要大约30%的时间才能从磁盘加载到RAM
  • 您的目标代码将占用约30%的内存空间
  • 您已有效地将内存带宽(用于目标代码)降低了约20%
  • 您已有效地将指令缓存的大小降低了约20%

这对性能有不可忽略的负面影响。

仅当您可以以某种方式“回购”这些性能成本时,这样做才有意义。基本上,有两种方法可以执行此操作:您需要执行很多64位整数数学运算,或者需要4个以上的GiByte映射内存。如果其中一个或两个都正确,那么使用64位软件是有意义的,否则就不行。

注意:在某些架构中,没有相应的32位或64位变体。在那种情况下,这个问题显然是没有道理的。最著名的是IA64(仅64位,没有32位变体),以及x86 / AMD64,尽管它们之间有着密切的联系,但它们的体系结构密切相关,其中x86仅32位,AMD64仅64位。

实际上,后一个陈述不再是100%正确的。Linux最近添加了x32 ABI,它允许您使用32位指针运行AMD64代码,因此,即使这不是“适当的” CPU架构,它也是一种使用AMD64架构的方式,就好像它具有本机一样。 32位变体。这正是做,因为我上面提到的性能开销是造成真正在现实世界的系统上运行的实际代码现实世界的用户可衡量的,可量化的问题。


8
与x86相比,amd64中的额外寄存器和指令呢?这能在多大程度上提高性能?
Filip Haglund

2
Google,用于在MacOS X和iOS上的Objective-C中使用的“标记指针”。大量对象没有分配任何内存,但是整个对象在64位系统上的指针中被伪造。(我听说Java做过类似的事情)。在C ++中,64位的std :: string通常在对象本身中最多包含22个字符,而没有任何内存分配。大量节省内存并提高速度。
gnasher729 '16

3
指针和整数的大小是多少?在大多数64位架构中,较大的地址空间和附加寄存器又如何呢?

1
由于指令集完全不同(并且通常效率更高)
所以

3
“这对性能产生了不可忽略的负面影响。” 尽管从绝对意义上说这句话是正确的,但它忽略了以下事实:绝大多数应用程序的性能瓶颈不在加载时间,内存使用/带宽或高速缓存中的指令数量上。
伊恩·肯普

6

如果软件需要直接与旧版系统,驱动程序或库连接,则您可能需要提供32位版本,因为AFAIK操作系统通常(绝对是Windows和Linux AFAIK)不允许将64位和32位混合使用进程中的位代码。

例如,如果您的软件需要访问专用硬件,那么客户使用只有32位驱动程序可用的旧型号的情况并不少见。


2
可以在Windows和Linux中的同一过程中混合使用32位和64位:stackoverflow.com/q/12716419/703382
Navin

1
@Navin:但是实用吗?您可以在64位Windows应用程序中使用COM组件吗(例如标记为在64位Windows版本上运行的任何CPU的.NET应用程序)?
彼得·莫滕森

3

如果您的软件是DLL,则必须同时提供32位和64位版本。您不知道客户将使用32位还是64位软件与DLL进行通信,并且DLL必须使用与应用程序相同的位长。这是不可谈判的。

如果您的软件是独立的可执行文件,则不太清楚。如果不需要在较早的操作系统上运行软件,则可能不需要提供32位版本。只需坚持使用64位,指定它需要64位操作系统即可完成工作。

但是,如果确实需要在较早的OS上运行软件,则可能希望提供64位版本。如果您有两个版本,那么您将进行两次测试,并且跨各种OS版本和语言正确测试软件并不是一个快速过程。由于32位软件可以在64位平台上完美地运行,因此软件仅以32位版本发行仍然很普遍,尤其是对于较小的开发人员。

另请注意,大多数手机都是32位的。也许现在有些高端的是64位的,但是没有什么令人信服的理由采取这一步骤。因此,如果您正在开发跨平台并且可能希望您的代码也可以在Android上运行,那么保持32位是一个安全的选择。


我反对您减少测试的立场。相反,我会争辩说要在多个平台上进行测试,尤其是不仅要使用不同的寄存器大小,还要使用不同的字节顺序,这是增加测试并捕获细微错误的简便方法。此外,我还将在不符合建议的最低硬件要求的计算机上进行测试,因为这还会暴露其他问题,除非使用非常大的数据集,否则这些问题可能不会出现。
hildred '16

@hildred拥有无限的测试资源,我同意。但是实际上,如果您对目标有更多的控制权,则可能不需要立即进行此测试。这也不是“简单的方法”-确保可以在VM中模拟其中的某些平台,但是如果需要设置物理硬件,则需要大量的手动(非自动化)工作。它可能使您不必编写测试工具来显式地对此进行测试,但是它绝不是免费的。
格雷厄姆

1
不是免费的,但价格便宜。如果将非平台测试限制为自动化测试,偶发性白痴测试和使用过的硬件,那么除了初始设置外,您在成功进行初始测试后进行成功测试的成本将受限于功耗和每次测试大约需要7个人工时。失败测试的成本当然会更高,但是通常这些测试的价值更高(总是存在硬件故障)。这种类型的设置对c程序员特别有用,因为它很容易暴露出某些类别的指针问题,而这些问题否则很难追踪。
hildred '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.