acm-header
登录

ACM通信

实践

通往64位的漫长之路


通用微处理器组件

iStockPhoto

莎士比亚的文字经常描写他做梦也想不到的情况。辛苦与烦恼伴随主要的计算转变,即使人们提前计划。未来的大部分软件仍将由几十年前的决策驱动。过去的决定会产生意想不到的副作用,这些副作用会持续几十年,而且很难撤消。

例如,考虑到32位微处理器系统演化为64/32比特处理器的过程,这个过程太长,通常很尴尬,有时还会引起争议,因为需要处理更大的存储并运行32位和64位用户程序的混合。大多数主要的通用cpu现在都有这样的版本,所以比特数“翻了一番”,但“辛苦和麻烦”并没有结束,尤其是在软件领域。

这个例子说明了硬件、语言(特别是C)、操作系统、应用程序、标准、基于安装的惯性和行业政治的交互。我们可以从中吸取经验教训,从高级策略到编程细节。

回到顶部

基本问题(20世纪80年代末)

耗尽地址空间是计算领域的一个悠久传统,而且通常是可以预测的。摩尔定律使得DRAM每三到四年就增长大约四倍,到20世纪90年代中期,人们能够为中端微处理器系统提供2GB到4GB的内存,这时简单的32位寻址(4GB)就会变得很尴尬。理想情况下,64/32位cpu应该很早就开始发布(1992年),在实际需要它们之前就已经占了相关安装基础的大部分。然后人们可以切换到64/32位的操作系统,并停止升级仅32位的系统,从而实现平稳过渡。供应商的发货时间自然各不相同,但发货时间从“勉强及时”到“相当晚”不等。这有点奇怪,考虑到地址位不足的悠久而众所周知的历史,再加上摩尔定律的明确可预测性。通常情况下,客户无法使用他们可以轻易负担得起的内存。

有些设计决策很容易改变,但有些则会产生长期的遗留问题。下面列举的例子包括:

  • 一些不幸的决定可能是由真正的限制所驱动的(1970:pdp -1116位)。
  • 20年的回顾证明,当时合理的决策是次优的(19761977:C数据类型的使用)。一些更好的使用建议可能会在以后省去大量的工作和麻烦。
  • 有些决定产生了短期的利益,但带来了长期的问题(1964:S/360 24位地址)。
  • 可预测的趋势被忽视,或者过渡努力被低估(1990年:32-> 64/32)。

约束。硬件人员需要在正确的时间构建64/32位cpu——太早(额外的成本,没有市场),也不太晚(竞争,愤怒的客户)。现有的32位二进制文件需要在向上兼容的64/32位系统上运行,它们可以被期望永远共存,因为许多永远不需要64位。因此,32位不可能是一个暂时的兼容特性,在以后的芯片中被迅速丢弃。

软件设计人员需要就整套标准达成一致;构建双模式操作系统、编译器和库;并修改应用程序源代码,使其在32位和64位环境中都能工作。必须正确处理大量细节,以避免冗余的硬件工作,并保持软件的健全。

解决方案。虽然不是没有微妙的问题,硬件通常是简单的,而且不是那么昂贵的第一个商用64位微处理器的64位数据路径最多增加了5%的芯片面积,这一比例在后来的芯片中迅速下降。大多数芯片使用相同的通用方法,将32位寄存器扩展到64位。软件解决方案要复杂得多,包括关于64/32位C语言、现有软件的性质、供应商之间的竞争/合作、官方标准和有影响力但完全非官方的特设小组的争论。

遗产。IBM S/360已经有40年的历史了,仍然支持24位传统寻址模式。64/32解决方案最多只有15年的历史,但将永远有效地与我们同在。五千年后,有些软件维护人员还会嘟囔着:“他们怎么这么笨?”4

通过大量的工作,我们设法度过了千年虫问题。我们还在处理64/32。我们还有其他类似的问题吗?64位cpu是否足以解决“Unix 2038”问题,或者我们是否需要在这方面更加努力?我们会用完64位系统吗?到时候我们该怎么办?IPv6会很快被广泛应用吗?

所有这些都是长期存在的问题的例子,对于这些问题,适度的远见可能会省去以后的辛劳和麻烦。但是软件就像政治一样:有时我们会等到问题变得非常痛苦时才去解决它。

回到顶部

问题:CPU必须寻址可用内存

任何CPU都可以有效地寻址一定数量的虚拟内存,最方便的方法是平面寻址,在平面寻址中,整数寄存器中的所有或大部分位形成一个虚拟内存地址,该地址可能比实际的物理内存多或少。一旦负担得起的物理内存超过了容易寻址的内存,就不再容易将内存用于性能问题,编程复杂性将迅速上升。有时,分段内存方案的使用有不同程度的成功和编程痛苦。历史上充满了笨拙的扩展,添加一些比特来延长几年的产品寿命,通常以操作系统人员的辛勤工作为代价。

几十年来,摩尔定律增加了可负担的内存。磁盘的增长甚至更快,特别是自1990年以来。较大的磁盘指针比较小的磁盘指针更方便,尽管没有内存指针重要。它们在使用映射文件时相互作用,迅速消耗虚拟地址空间。

在20世纪80年代中期,一些人开始考虑64位微处理器,例如,由DEC(数字设备公司)建立的实验系统。MIPS计算机系统公司在1988年底决定,它的下一个设计必须是一个真正的64位CPU,并在1991年发布了R4000。许多人认为MIPS是疯狂的,或者至少是不成熟的。我认为这个系统刚好赶上开发软件来匹配不断增加的DRAM,我写了一篇文章来解释原因。5从那以后,这些问题没有太大变化。

n位CPU。根据长期的习惯,一个N位CPU实现了一个ISA(指令集架构),具有N位整数寄存器和N(或接近N)个地址位,忽略了总线或浮点寄存器的大小。许多32位isa都有64位或80位浮点寄存器,实现有8位、16位、32位、64位或128位总线。有时营销人员会混淆这一点。我在这里使用术语64/32位来区分新微处理器和老的64位面向字的超级计算机,因为软件问题有些不同。在同样的意义上,Intel 80386可能被称为32/16位CPU,因为它保留了对早期16位模型的完全支持。

为什么2 n位?人们有时希望使用宽字计算机来提高并行位操作或数据移动的性能。如果需要2n位的操作(加、乘等等),每一个操作都可以在2n位CPU上的一条指令中完成,但在n位CPU上需要更长的序列。这些都是简单的低级性能问题。然而,使用更宽的字的典型的令人信服的原因是需要增加地址位,因为具有足够地址位的代码可能需要全局重构来生存更少的位。

寻址虚拟与现实在通用系统中。用户虚拟地址被映射到真实的内存地址,操作系统将需要的代码或数据从磁盘映射到内存中,可能会出现页面故障。用户程序最多可以访问VL(虚拟限制)字节,其中VL从某些硬件限制开始,然后有时会将更多的空间丢失给操作系统。例如,32位系统的vl很容易为4、3.75、3.5或2GB。一个给定的程序执行最多使用PM(程序内存)字节的虚拟内存。对于许多程序来说,PM可以根据输入的不同而有很大的不同,但是当然PM VL。

RL(实际限制)对操作系统是可见的,通常受物理地址总线宽度的限制。有时,映射硬件被用来扩展RL,使其超出过小的“自然”限制(就像PDP-11s中发生的那样,稍后会描述)。已安装的AM(实际内存)对用户程序不太可见,并且在不同的机器上不需要不同版本的用户程序。

最常见的是VL RL AM。有些程序为了方便而消耗虚拟地址空间,当PM >>时实际上可以执行。AM:我看到过4:1仍然有效的情况,这是良好的局部性的结果。文件映射可以进一步提高这一比例,并且仍然有效。另一方面,有些程序在PM > AM时运行得很差,这证实了一句古老的谚语:“虚拟内存是出售真实内存的一种方式。”

有时,一个计算机家族从VL RL AM开始,然后AM增长,也许RL以只有操作系统才能看到的方式增加,这时VL << AM。单个程序根本不能使用容易购买的内存,这迫使工作被分割,使其更加困难。例如,在Fortran中,REAL X (M, M, M)的声明是一个三维数组。如果M = 100,X需要4MB,但人们希望相同的代码运行M = 1000 (4GB),或6300 (1000 gb)。有一些这样的系统确实存在,尽管它们并不便宜。我曾经有一个客户抱怨目前缺乏对1,000GB实际内存的支持,尽管后来该客户能够购买这样的系统并在一个程序中使用该内存。在那之后,客户抱怨缺乏10000 gb的支持…

当然,在多任务系统中增加AM对于提高驻留在内存中的任务数量或减少分页开销仍然是有用的,即使每个任务仍然受到VL的限制。如果操作系统代码可以直接且简单地寻址所有已安装的内存,而不必管理额外的内存映射、银行寄存器等,那么操作系统代码总是会得到简化。

地址位耗尽由来已久。

回到顶部

大型机,小型计算机,微处理器

经常被引用的乔治·桑塔亚纳(George Santayana)在这里说得很恰当:“那些不记得过去的人注定要重蹈覆辙。”

大型机。IBM S/360大型机(大约1964年;见随附的年表侧边栏)有32位寄存器,其中只有24位用于寻址,核心内存限制为16MB。这在当时被认为是巨大的。一个“大型”大型机最多提供1MB内存,尽管一些“大型”大型机可以提供6MB内存。大多数S/360不支持虚拟内存,因此用户程序直接生成物理地址,安装的AM在操作系统和用户程序之间进行分区。16MB的限制是不幸的,但是忽略(而不是捕获)高阶8位更糟糕。汇编语言程序员巧妙地将带有24位地址的8位标志包装成32位字。

由于虚拟寻址S/370(1970)启用了比物理内存所允许的更大的程序,随着核心让位给DRAM (1971), 16MB的限制变得不够用。IBM 370XA cpu(1983)增加了31位寻址模式,但为了向上兼容保留了(必要的)24位模式。我曾经是那些“聪明”的程序员之一,我有点惊讶地发现,一个最初编写于1970年的大型程序(S/360 ASSIST汇编程序)在2006年仍在使用24位兼容模式,因为它不能以任何其他方式运行。曾经“聪明”的编译器代码早就停止这样做了,但是汇编代码就更难了。(“人所做的恶在死后仍会存在,善往往随他们的尸骨而埋葬。”莎士比亚,凯撒大帝)

然后,对于某些应用程序,特别是数据库,甚至31位寻址也不够用。ESA/370(1988)提供了用户级分段来访问多个2GB的内存区域。

64位IBM zSeries(2001)在40多年后仍然支持24位模式。为什么会出现24位?有人告诉我,这一切都是为了一款低成本的早期型号,360/30,32位的运行速度会更慢,因为它有8位的数据路径。这些船最后一次装船是在30多年前。他们值得数十年的头疼吗?

微型计算机。在16位DEC PDP-11小型计算机家族(1970年)中,单个任务只处理64KB,或者在后来的型号(1973年)中,64KB的指令加上64KB的数据。“在计算机设计中,最大、最常见的错误是没有为内存寻址和管理提供足够的地址位,”c·戈登·贝尔和j·克雷格·穆奇在1978年写道。PDP-11遵循了这一神圣的传统,即在地址位上节省,但它的原则是,一个好的设计至少可以通过一个主要的变化来发展。对于PDP-11,有限的地址空间在短期内得到了解决,但没有足够的技巧来支持一个大的小型计算机家族。这的确是一个代价高昂的疏忽。”2

公平地说,使用32位硬件很难达到PDP-11的成本目标,但我认为DEC确实低估了DRAM内存价格下降的速度。无论如何,这种情况持续了很长时间——PDP-11最终在1997年停产!

PDP-11/70(1976)增加了可支持的并发任务的数量,但任何单个程序仍然只能使用最多4MB的64KI + 64KD,因此单个大型程序需要不自然的行为来将代码和数据分割成64KB的片段。有些人认为这鼓励了模块化,抑制了“爬行功能主义”,因此在哲学上是好的。

虽然32位的VAX-11/780(1977)只比PDP-11/70略快,但增加的地址空间是一个重大改进,终结了高端pdp -11的发展。VAX架构师William Strecker是这样解释的:“然而,有些应用程序的编程在65KB的地址空间中是不切实际的,也许更重要的是,有些应用程序的编程通过拥有大的地址空间而明显简化了。”7

微处理器。Intel 8086的16位ISA似乎很可能成为PDP-ll问题的牺牲品(1978)。不过,它确实为显式段操作提供了用户模式机制。这允许一个程序访问超过64KB的数据。PC程序员熟悉内存模型、库、编译器标志、扩展器和其他曾经需要的构件的多样性。80386提供32位的平面地址(1986),但当然保留了早期的机制,16位PC软件“永远”存在。中间的80286(1982)说明了修补一个体系结构以获得更多寻址位的困难。

32位的摩托罗拉MC68000(1979)开始采用平面寻址编程模型。通过忽略32位寄存器的高8位,它完全重复了S/360的错误。再一次,“聪明的”程序员找到了这些比特的用途,当MC68020(1984)解释所有32位时,一些程序崩溃了(例如,当从最初的苹果Macintosh迁移到Mac II时)。

幸运的是,64位cpu成功地避免了重复S/360和MC68000问题。尽管早期版本通常实现40到44个虚拟地址位,但它们捕获了尚未实现的高阶v位的使用,而不是忽略它们。人们最终还是会学习的。

回到顶部

教训

  • 即使在顶级架构师创建的成功的计算机家族中,地址位也是稀缺的,迟早会被完全消耗掉。
  • 向上的兼容性是一个真正的约束,提前思考会有所帮助。在大型机的情况下,一个24位的“首次实现工件”需要40多年的硬件/软件支持。然后,一个成功的小型计算机家族的进化过早地结束了。最后,微处理器重复了早期的错误,尽管X86的分割允许存活足够长的时间获得平面地址版本。

回到顶部

20世纪80年代末32到64位的问题

到了20世纪80年代末,摩尔定律似乎在硅中得到了验证,很明显,到1993 - 1994年,中端微处理器服务器可以提供2GB-4GB或更多的物理内存,而且成本效益很高。我们看到真正的程序有效使用的虚拟内存比安装的物理内存多4:1,这在1993 - 1994年意味着压力,到1995年意味着真正的麻烦。正如我写的字节1991年9月:5

“虚拟寻址方案通常会超过可能的物理地址的限制。64位地址实际上可以处理一座内存山:假设1兆内存需要1立方英寸的空间(使用4兆DRAM芯片),2**64字节将需要一平方英里的DRAM堆超过300英尺高!目前,没有人期望解决这么多的DRAM,即使是下一代16MB DRAM芯片,但将物理内存增加到略高于32位肯定是一个目标。使用16MB DRAM芯片,2**32字节适合1立方英尺多一点(不包括冷却)的桌面系统可行…

数据库系统经常将一个文件分散在多个磁盘上。当前的SCSI磁盘最多可容纳2g(即,它们使用31位地址)。将文件位置计算为虚拟内存地址需要整数算术。操作系统习惯于围绕这些问题工作,但它变得不愉快的变通办法;程序员不只是让东西工作得很好,而是努力让东西工作....”

所以,人们开始做一些事情来解决这个问题。

SGI(硅图形)。从1992年初开始,所有新的SGI产品都只使用64/32位芯片,但最初它们仍然运行32位操作系统。1994年底,针对大型服务器推出了64/32位操作系统和编译器,能够同时支持32位和64位用户程序。这种软件沿着产品线的方向发展。一些客户很快就购买了超过4gb的内存,并在一天之内重新编译程序来使用它,在某些情况下,仅仅通过更改一个Fortran参数。然而,低端SGI工作站多年来一直使用32位操作系统,当然,必须支持现有的32位硬件……好多年了。由于历史原因,SGI的32位和64位指令集的种类比真正需要的要多,所以它比只有两个指令集还要糟糕。

这是一种糟糕的“长尾”,人们关注的是“首次发布日期”,但通常“最后发布日期”更重要,就像“我们将在该系统上运行的操作系统或应用程序的新版本发布的最后日期”一样。在80386问世20年之后,Windows 16位应用程序仍然运行在普通的Windows XP上。Windows XP x64最终放弃了这种支持。

12月。DEC在1992年底推出64位Alpha系统,采用64位操作系统,到1994年底推出内存大到需要大于32位寻址的服务器。DEC可能要求32位端口,但从长远来看,它直接选择了64位,以避免重复。清除第三方软件64位的时间和金钱是昂贵的,但它对行业来说是有价值的,因为它加速了64位的清理。DEC这样做可能是正确的,因为它没有32位Alpha程序的安装基础,可以避免必须支持两种模式。对于VMS,早期版本是32位的,后期版本是64/32位的。

其他供应商。在接下来的几年里,许多供应商都推出了64位cpu,通常运行32位软件,后来是64/32位:Sun UltraSPARC (1995), HAL SPARC64 (1995), PA-RISC (1996), HP/UX 11.0 (1997), IBM RS64和AIX 4.3 (1997), Sun Solaris 7 (1998), IBM zSeries (2001), Intel Itanium (2001), AMD AMD64 (2003), Intel EM-T64a (2004), Microsoft Windows XP x64(2005)。Linux 64位版本出现在不同的时期。

大多数64位cpu被设计为现有32位体系结构的扩展,可以很好地运行现有的32位二进制文件,通常通过在64位模式下将32位寄存器扩展到64位,而忽略32位模式下的额外位。这些发布的时间跨度很长,这是由于优先次序的自然差异造成的。SGI对高性能技术计算特别感兴趣,这些用户习惯于64位超级计算机,通常只要在Fortran程序中增加一个数组维度并重新编译就可以使用64位。SGI和其他大型服务器供应商也关心大型数据库应用程序的内存。对于X86 CPU供应商来说,这当然不那么重要,因为它们的容量主要由pc占据。在英特尔的情况下,可能是对Itanium的重视推迟了64位x86的发布。

到2006年,4GB的DRAM(通常由1GB的DRAM组成)通常使用4个dimm,价格可能低于400美元,而300GB的磁盘则以每GB不到1美元的价格广泛供应,因此人们预计到那时对64位的广泛支持已经成熟。然而,所有这一切花费的时间可能比它应该花的时间要长,而且已经有很多年,人们可以购买内存,但不能方便地寻址它,或者不能购买一些第三方应用程序,因为这些应用程序自然滞后于64位cpu。尽管这个即将发生的问题是众所周知的,但我们仍有必要了解它发生的原因和方式。

回到顶部

教训

  • 对于任何成功的计算机家族来说,将硬件的安装基础进行转换都需要很长时间,而软件的使用时间更长。
  • 从32位到64/32位是一个长期共存的场景。与过去的转换不同,几乎所有64位cpu都必须运行兼容现有的32位二进制文件,而不需要进行转换,因为大部分已安装的基础仍然是32位的,大量32位程序完全够用,并且可以无限期地保持这种状态。

回到顶部

软件更难

构建64位CPU是不够的。嵌入式系统市场比通用市场更容易发展,例如Cisco路由器和使用64位MIPS芯片的任天堂n64。然而,大多数32位系统的供应商必须通过以下所有步骤来生产有用的向上兼容的64位系统:

  1. 使用64/32 cpu的系统,可能以32位模式运行。继续支持只支持32位的cpu,只要它们已经上市,并且在之后的几年(通常是5年或更长时间)。大多数供应商这样做,只是因为软件开发需要时间。
  2. 为C、c++和其他语言选择64位编程模型。这包括与标准机构的讨论和与竞争对手的协商。如果你选择了与大多数竞争对手不同的模式,可能会有严重的后果。Unix供应商和微软确实有不同的选择,原因貌似合理。仔细想想中间语言的问题fortran要求INTEGER和REAL的大小相同,这使得64位的默认整数很尴尬。
  3. 仔细清理头文件。
  4. 构建编译器以生成64位代码。编译器本身几乎肯定以32位模式运行并交叉编译为64位,尽管偶尔会有大型机器生成程序需要以64位模式运行的编译器。注意,程序员的健全通常需要一个引导步骤,在这个步骤中,32位编译器首先被修改为接受64位整数,然后重新编码以使用它们本身。
  5. 将操作系统转换为64位,但也使用32位接口,以运行64和32位应用程序。
  6. 创建所有系统库的64位版本。
  7. 在新的64位硬件上发布新的操作系统和编译器,希望在已经发布了一段时间的早期64位硬件上发布。这包括支持每个库的(至少)两种风格。
  8. 说服第三方软件供应商支持与此相关的任何程序的64位版本。在这个过程的早期,安装基础不可避免地保持32位,软件供应商考虑潜在的市场规模和在同一个平台上支持两个版本的成本。DEC通过购买大量64位Alpha端口,帮助业界解决了32位到64位的可移植性问题。
  9. 停止提供32位系统(但继续支持它们很多年)。
  10. 最后,在新的操作系统版本中停止支持32位硬件。
  11. 从第1步到第6步通常需要两到三年的时间,而完成第9步则需要几年的时间。该行业尚未完成第10步。

操作系统供应商可以避免第1步,但除此之外,问题是相似的。许多程序从来不需要转换为64位,特别是因为许多操作系统已经支持32位程序的64位文件指针。

接下来,我将追溯发生在20世纪90年代的一些曲折,特别是涉及到在64/32位cpu上实现C。这个话题引发了无休止的、有时甚至是谩骂的讨论。

回到顶部

C: 64位整数,64/32位cpu: Technology and Politics

人们使用了各种(并不总是一致的)符号来描述C数据类型的选择。在伴随的表格在美国,据我所知,第一个标签是最常见的。在使用8位char的机器上,short通常是16位,但其他数据类型可能不同。常用的选择见下表。

早期的天。仅包括早期的C整数(1973)int而且字符;然后而且是1976年增加的,紧随其后的是无符号而且类型定义在1977年。在20世纪70年代末,16位pdp -11的安装基础被更新的32位系统所取代,这要求源代码在16位系统(使用I16LP32)和32位比特系统(ILP32)之间是有效的、可共享的,并且兼容的,这种匹配工作得很好。pdp -11仍然使用(有效的)16位int大多数情况下,但可以根据需要使用32位。32-bitter使用32-bitint大多数情况下,这是更有效的,但可以表示16位via.避免使用用于在机器之间通信的数据结构int.32位非常重要可在PDP-11上使用。在此之前,PDP-11需要显式函数来操作int[2](16位int对),这样的代码不仅尴尬,而且不能简单地与32位系统共享。这是非常重要的一点对于32位cpu来说并不是必须的,但是在16位和32位环境之间支持代码共享是非常重要的。我们本来可以用char,短,int如果我们所有的系统都是32位的。

在这一点上,记住C的本质是很重要的。花了一段时间类型定义成为常用的习语。20/20的事后诸葛亮认为,提供一套标准的typedef表示“快速整数”,“保证是精确的n位整数”,“大到足以容纳一个指针的整数”,并建议人们根据这些定义构建自己的类型定义,而不是基类型。如果这样做了,也许许多辛劳和麻烦就可以避免了。

然而,这将是非常反文化的,它需要惊人的预感。贝尔实验室已经在36位cpu上运行了C语言,并致力于可移植性,因此像“intl6”这样过于特定的结构可能会被视为不受欢迎。C编译器仍然必须在64KI+64KD pdp -11上运行,所以语言的最小化是非常重要的。C/Unix社区相对较小(600个系统),并且刚刚开始适应即将到来的32位小型机。在1977年底,已知最大的Unix安装有7个pdp -11,总共有3.3MB内存和1.9GB磁盘空间。没有人能够预料到C语言及其分支会变得如此普遍,64位cpu也不是首要问题。

32位的快乐时光。在20世纪80年代,ILP32成为规范,至少在基于unix的系统中是这样。这是一段快乐的时光:32位的DRAM在很多年里都足够买到。然而,现在回想起来,这可能会导致一些人在假设时变得草率Sizeof (int) == Sizeof (long) == Sizeof (ptr) == 32

大约在1984年的某个时候,Amdahl UTS and凸补充道很久很久对于64位整数,前者在32位体系结构上,后者在64位体系结构上。UTS特别将此用于长文件指针,这也是PDP-11 Unix(1977)中使用long的动机之一。Algol 68在1968年启发了long long,它也在某个时候被添加到GNU C中。许多人斥责这种语法,但至少它不再消耗保留关键字。

当然,16位int在Microsoft DOS和Apple Macintosh系统上使用,考虑到最初使用的是Intel 8086或MC68000,其中32位int会很昂贵,特别是在早期的8位或16位数据路径的系统上,低内存成本尤其重要。

64位在1991 /1992年开始升温。MIPS R4000和DEC Alpha在20世纪90年代早期发布。在1990年到1992年期间,关于64位C的合适模型的电子邮件讨论在不同的公司中非常猖獗,特别是当在仍然会运行32位应用程序很多年的系统上实现时。通常情况下,这种非正式合作存在于为竞争对手工作的工程师之间。

1992年中期,Sun的Steve Chessin发起了一个非正式的64位C工作组,看看供应商能否避免实现随机不同的64位C数据模型和命名法。系统和操作系统供应商都担心客户和第三方软件供应商的愤怒。DEC选择了LP64,并且已经走了很远,因为Alpha没有32位版本。SGI提供64位硬件,开发64位编译器和操作系统;它也更喜欢LP64。其他许多人正在计划64位cpu或操作系统,并进行可移植性研究。

Chessin的工作小组没有正式的地位,但是有来自许多系统和操作系统供应商的受人尊敬的高级技术人员,包括几个C标准委员会的成员。有了这么多脑力,人们可能会希望有一个明确的答案出现,但这是不可能的。这三种方案(LLP64、LP64和ILP64)中的每一种都破坏了不同类型的代码,这是基于32位“快乐时光”中所做的特定隐式假设。

团队中受人尊敬的成员发表了可信的演讲,引用了大量的代码分析和移植经验,每个人的结论是:“XXX这就是答案。”不幸的是,XXX在每个案例中都是不同的,小组仍然分成三部分。在这一点上,我建议我们也许可以在头文件上达成一致,这将帮助程序员生存(导致<inttypes.h>)。大多数人都同意这一点很久很久是其他表示法中最不糟糕的,并且有一些以前的用法。

我们担心我们比即将到来的C标准早了好几年,但不能等待它,C标准委员会的成员对此表示支持。如果我们在任何合理的事情上达成一致,并且它成为普遍的做法,它至少会得到应有的考虑。不管你喜不喜欢,在那个时候,这个非官方组织可能很久很久也许这种必然性可以追溯到1984年。

到1994年,DEC推出了大型系统,并使用LP64为许多第三方软件端口付费。SGI还提供了支持ILP32LL和LP64的大型系统很久很久填补了在20世纪70年代末由long处理的角色。

DEC的努力证明,在不使许多软件32位不干净的情况下使其64位干净是可行的。SGI的工作证明了32位和64位程序可以在一个系统上得到合理的支持,并具有合理的数据交换,这是大多数其他供应商的要求。实际上,这意味着人们应该避免在用于交换数据的结构中,完全类似于避免int在PDP-11/VAX的日子。大约在1995年的这个时候,大文件峰会同意Unix api将文件大小增加到2GB以上,使用很久很久作为基本数据类型。

最后,Aspen小组在1995年又进行了一轮关于Unix 64位C模型的讨论,最终选定了LP64,至少部分原因是它已经被证明是可行的,而且大多数实际的64位软件都使用LP64。

在1992年64位C小组会议期间,微软还没有选择它的模型,但后来选择了LLP64,而不是Unix供应商首选的LP64。有人告诉我,这是因为pc中唯一的32位整数类型是;因此,人们经常使用比Unix代码更明确地表示32位。这意味着改变它的大小往往会比在Unix中破坏更多的代码。这在我看来似乎是合理的。每个选择都打破了一些代码,因此人们会查看自己的代码库,这些代码库有所不同,导致了合理的意见分歧。

许多人鄙视很久很久甚至在1999年它被纳入下一个C标准之后,新闻组里仍然充斥着反对它的观点。任何想要了解血腥细节的人都可以咨询C标准的官方原理。6

多年来,对各种数据类型的大小产生了不同的隐含假设,造成了大量的混乱。如果我们能回到1977年,知道我们现在所知道的,我们可以简单地通过坚持更一致地使用类型定义.然而,在1977年,很难想象20年后64位的微型电脑才刚刚发展到32位的迷你电脑!

如果更多的供应商在1992年就已经在64位实现上更进一步,这个过程可能也会得到简化。许多人要么忘记了PDP-11/VAX时代的教训,要么没有参与其中。在任何情况下,64/32系统都有更严格的要求:64位和32位程序将永远在同一个系统中共存。

时机对于制定良好的行业标准很重要。过早地编写标准可能没有足够的实践经验,因为没有人有真正的实现可以从中学习。太晚了,供应商很可能已经承诺了许多不兼容的实现。在这两者之间,一些小组有早期的实现,以帮助通知标准。也许是偶然的,64位C标准的出现恰逢其时。

回到顶部

教训

  • 标准通常以非标准的方式产生,而且事实上的标准往往早于官方标准。
  • 通情达理的人可能不同意,尤其是在看到不同的数据集时。
  • 有时,一个人必须与竞争对手合作,才能让任何合理的事情发生。
  • 程序员利用了额外的位或规范的模糊性。大多数争论的发生是因为应用程序程序员做出了不同的隐式假设。
  • 代码可以重新编译,但是一旦数据写入某个地方,任何新的代码都必须能够清晰地描述数据。目前的软件很少从头开始,而是必须存在于一个大的生态系统中。
  • 我们可能永远不会构建128位的计算机,但为128位整数发明一种表示法可能会很好,它在64位cpu上生成的代码与在32位cpu上生成的64位代码几乎相同。在真正需要之前就这么做是很好的。一般来说,可预测的长期问题最有效的解决方法是制定一些计划,而不是在问题迫在眉睫时进行疯狂的努力。幸运的是,128-bitters还需要很多年,如果有的话(可能是20202040年),因为我们的地址规模增加了40亿,这将持续一段时间,即使摩尔定律持续那么久!然而,如果在2020年出现128位,那么在2010年左右考虑下一个整数大小将是明智的。
    当然,当S/360推出时,IBM和其他供应商都有36位和18位的产品线。在另一个宇宙中,如果S/360是36位架构,每个字有4个9位字节,那么大多数后来的机器将是18位和36位的,而我们将刚刚开始36位到72位的过渡。
  • 硬件决策持续很长时间,但软件决策可能持续得更久。如果您是一名实践程序员,请同情那些最终维护您的代码的人,并花些时间提前考虑。允许硬件的自然扩展,隐藏底层细节,并尽可能使用最高级别的语言。C语言高效使用硬件的能力可能是福也是祸。

回到顶部

结论

有些决定会持续很长时间。1964年S/360的24位寻址方式至今仍在使用,正如20世纪70年代中期C语言使用的一些副作用一样。由于许多原因,向64位的过渡可能比所需的时间要长。糟糕的是,人们经常无法使用负担得起的内存来解决性能问题或避免繁琐的编程。

太糟糕了,有这么多的“辛苦和麻烦”,但微处理器的“双”已经实现,软件的“双”至少正在进行中,人们已经停止争论64位微处理器的必要性。

回到顶部

参考文献

1.Aspen数据模型委员会。64位编程模型:为什么是LP64?(19971998);www.unix.org/version2/whatsnew/lp64_wp.html。

2.Bell C.G.和Mudge, J.C. PDP-11的进化,计算机工程:计算机系统设计的DEC视角。CG。贝尔,j。c。穆奇,和j。e。麦克纳马拉。数字出版社,贝德福德,MA, 1978,

3.Josey, A.数据大小中立和64位支持(1997);www.usenix.org/publications/login/standards/10.data.html。

4.语言,关卡,库,寿命。ACM队列2,9(20042005), 3238。

5.64位计算。字节(1991年9月),135142。9(完整的文本也可以通过搜索谷歌Groups comp.arch: Mashey BYTE 1991找到)。

6.国际标准编程语言的基本原理;www.open-std.org/jtcl/sc22/wg14/www/docs/n897.pdf(或其他网站)。

7.Strecker, W.D. VAX-11/780: DEC PDP-11家族的虚拟·地址扩展。计算机工程:计算机系统设计的DEC视角。CG。贝尔·J.C.穆奇,J.E.麦克纳马拉,艾德。数字出版社,贝德福德,麻州,1978。

8.Unix规范;增加对任意文件大小的支持;www.unix.org/version2/whatsnew/Lfs20mar.html。

回到顶部

作者

约翰Mashey是风险投资家和科技公司的顾问,是初创公司的各种技术顾问委员会的成员,也是计算机历史博物馆的受托人。除了在贝尔实验室花了10年时间研究Unix的程序员工作台版本之外,他还是MIPS RISC体系结构的设计师之一,SPEC基准测试小组的创始人之一,以及Silicon Graphics的首席科学家。

回到顶部

脚注

本文的以前版本发表在ACM Queue的2006年10月号上。

DOI: http://doi.acm.org/10.1145/1435417.1435431

回到顶部

UT1表格常见的C数据类型。

回到顶部


©2009 acm 0001-0782/09/0100 $5.00

允许为个人或课堂使用本作品的全部或部分制作数字或硬拷贝,但不得为盈利或商业利益而复制或分发,且副本在首页上附有本通知和完整的引用。以其他方式复制、重新发布、在服务器上发布或重新分发到列表,需要事先获得特定的许可和/或付费。

数字图书馆是由计算机协会出版的。版权所有©2009 ACM, Inc.

Baidu
map