64位编程模型:为什么要使用LP64(三)
2013-08-24 15:39
246 查看
原文出自这里
目前已经上市的LP64的操作系统已经通过了现有的许多规范和认证。当然我们观察发现,即使没有大的障碍,但还是有相当一部分的细节不能满足当前的规范和认证。在开放式软件社区,LP64系统已经被证实可以符合一些重要的商业标准,但是目前为止还没有在LLP64和ILP64上有类似的例子。
另外特别注意,一些最标准,特别的语言规范比如ANSI C却在基本数据类型宽度的问题上不太在意,因为历史表明,不同的选择都会反映到底层架构中。在不同的C编译器之间,以及在同一个编译器不同的优化级别之间,这些都会导致同一份代码被解释成不同的意义。有时候这种差异会导致一些工作中的问题,但是一些写的比较好的代码和工具,比如lint可以显著减少这些问题的发生。此外,在各个不同厂商的平台之间移植应用程序的经验也有助于找出这类问题。然而,在实例和实际问题中总有这类问题存在——开发者需要大量的工作来修正这类问题。如果使用LP64,我们将会有现成很多经验可以参考,这些经验来自操作系统的作者和大量应用程序开发者。
为了实现各种编程模型,会需要额外加入一些指令。不过编译器开发者一般都有丰富的经验来处理一类的优化。
例如,在LP64中,int型和long型混合计算时,只需要将int型数据执行带符号的扩展。由于大多数的整型表达式都不包括long型数据,因此编译器可以很聪明地仅仅是在必要时做一次有符号扩展操作。大多数目前的架构(Alpha、MIPS、Sparc
V9和PowerPC)在做有符号扩展的时候都会有一次32位的加载(load)操作,因此他们没有这个问题,不过他们会在处理无符号32位int数据时遇到类似的问题。鉴于大多数CPU都花费大量时间执行32位指令(无论是在运行64位程序还是仅仅是在64位代码中执行32位的操作),似乎很难理解为什么许多代码实现都避免使用32位的操作。
在我们移植代码的过程中,这些编程模型内部实现的问题从来没有对商业应用程序的性能造成大的影响。而且内存周期和CPU周期之间的平衡性的处理也可以抵消额外的时钟周期。
在一些重要的商业应用中有时候会遇到一个更大的问题,这就是如何处理更大的内存需求,以及如何将这些内存数据挂载到系统中。64位整型数需要32位整型数的两倍空间。此外,延迟效应的影响不可忽视,特别是对于磁盘,它可以消耗1百万个CPU时钟周期(一次磁盘操作需要3ms,而一个CPU时钟周期只有3ns)。int型作为目前C和C++程序中最常见的数据类型,将它定义成32位还是64位数据会对性能带来巨大的影响。
有一些软件厂商正在尝试使用ILP64,但是这类应用程序常常并没有享受到更大int空间带来的好处,却有更大的内存开销。
也有一些发行的ILP64系统(Cray和ETA)。尽管他们通过移植程序到ILP64证明了ILP也是可行的,不过ILP64远没有LP64系统所具有的广泛市场基础。
已经移植到LP64上的应用程序还需要一些代码审查,比如修改int的用法,优化在ILP64系统下的性能。许多大的独立软件开发商都需要单独的代码库来支持这种差异。这就是为什么很难看到这些额外代码修改工作带来的好处。
还没有为64位系统做出修改的应用程序已经有了现成的经验可以参考——通过迁移的文档或者是一些自动化工具。
兼容性:特别移植FORTRAN和C的混合代码,在LP64更容易兼容已有的数据类型。
互操作性:32和64位环境中可以使用同一套标准的数据类型。
标准的一致性:不管是在移植代码过程中还是在正式的工业标准的验证中,LP64都可以最好地兼容已有的工业标准。
性能是LP64位系统的一个主要卖点,虽然在应用程序中过度使用64位数据会造成非常大的内存开销。
可移植性,因为我们已经积累了相当多的成功的移植经验,所以可以很容易从目前的32位工业应用过渡到新的平台下。
所有这些,加上在64位环境可以支持C语言的所有原生数据类型,所有证据都表明LP64是最佳的选择。
业界标准
从技术上来说,开放式系统社区是由一系列API协议所组成的,例如X/Open,IEEE,ISO和OMG。这些文档花了很多年才开发出来,它将之前的经验标准化,并且制订新功能的协议。因此这些规范对于系统开发者、应用程序开发者和最终用户都有很重要的价值。有专门的机构负责验证规范是被正确实现,它为不同的客户提供相关认证。这些认证就像胶水一样将我们连结起来变成一个社区。任何会大量修改现有规范的64位模型都不太可能会被社区广泛认可。目前已经上市的LP64的操作系统已经通过了现有的许多规范和认证。当然我们观察发现,即使没有大的障碍,但还是有相当一部分的细节不能满足当前的规范和认证。在开放式软件社区,LP64系统已经被证实可以符合一些重要的商业标准,但是目前为止还没有在LLP64和ILP64上有类似的例子。
另外特别注意,一些最标准,特别的语言规范比如ANSI C却在基本数据类型宽度的问题上不太在意,因为历史表明,不同的选择都会反映到底层架构中。在不同的C编译器之间,以及在同一个编译器不同的优化级别之间,这些都会导致同一份代码被解释成不同的意义。有时候这种差异会导致一些工作中的问题,但是一些写的比较好的代码和工具,比如lint可以显著减少这些问题的发生。此外,在各个不同厂商的平台之间移植应用程序的经验也有助于找出这类问题。然而,在实例和实际问题中总有这类问题存在——开发者需要大量的工作来修正这类问题。如果使用LP64,我们将会有现成很多经验可以参考,这些经验来自操作系统的作者和大量应用程序开发者。
性能特征
我们认为,从经济的角度来看,64位计算在技术上的优势会使其成为主流。然而,有时候为了更加经济地解决问题却阻碍64位计算的普及。因此,各种编程模型在性能上的差异是64位计算是否能迅速普及的关键。在各种64位编程模型之间,我们能发现两种不同的差异:(1)不同编程模型上的指令周期开销,以及(2)内存数据传输成本(在所有不同层级的内存之间)。为了实现各种编程模型,会需要额外加入一些指令。不过编译器开发者一般都有丰富的经验来处理一类的优化。
例如,在LP64中,int型和long型混合计算时,只需要将int型数据执行带符号的扩展。由于大多数的整型表达式都不包括long型数据,因此编译器可以很聪明地仅仅是在必要时做一次有符号扩展操作。大多数目前的架构(Alpha、MIPS、Sparc
V9和PowerPC)在做有符号扩展的时候都会有一次32位的加载(load)操作,因此他们没有这个问题,不过他们会在处理无符号32位int数据时遇到类似的问题。鉴于大多数CPU都花费大量时间执行32位指令(无论是在运行64位程序还是仅仅是在64位代码中执行32位的操作),似乎很难理解为什么许多代码实现都避免使用32位的操作。
在我们移植代码的过程中,这些编程模型内部实现的问题从来没有对商业应用程序的性能造成大的影响。而且内存周期和CPU周期之间的平衡性的处理也可以抵消额外的时钟周期。
在一些重要的商业应用中有时候会遇到一个更大的问题,这就是如何处理更大的内存需求,以及如何将这些内存数据挂载到系统中。64位整型数需要32位整型数的两倍空间。此外,延迟效应的影响不可忽视,特别是对于磁盘,它可以消耗1百万个CPU时钟周期(一次磁盘操作需要3ms,而一个CPU时钟周期只有3ns)。int型作为目前C和C++程序中最常见的数据类型,将它定义成32位还是64位数据会对性能带来巨大的影响。
有一些软件厂商正在尝试使用ILP64,但是这类应用程序常常并没有享受到更大int空间带来的好处,却有更大的内存开销。
对目前的行业标准的兼容程度
到目前为止,现有代码大多都是移植到基于LP64平台的64位环境下。这些平台厂商都同社区中有64位应用程序开发者合作过。多年的市场经验也表明,现有的代码移植的解决方案非常有效。也有一些发行的ILP64系统(Cray和ETA)。尽管他们通过移植程序到ILP64证明了ILP也是可行的,不过ILP64远没有LP64系统所具有的广泛市场基础。
已经移植到LP64上的应用程序还需要一些代码审查,比如修改int的用法,优化在ILP64系统下的性能。许多大的独立软件开发商都需要单独的代码库来支持这种差异。这就是为什么很难看到这些额外代码修改工作带来的好处。
还没有为64位系统做出修改的应用程序已经有了现成的经验可以参考——通过迁移的文档或者是一些自动化工具。
总结
每个评价体系都需要更深入的研究(JimGray说过,计算是分形的,不管你怎么看,都有无限的复杂性),但是我们认为LP64是唯一的选择:兼容性:特别移植FORTRAN和C的混合代码,在LP64更容易兼容已有的数据类型。
互操作性:32和64位环境中可以使用同一套标准的数据类型。
标准的一致性:不管是在移植代码过程中还是在正式的工业标准的验证中,LP64都可以最好地兼容已有的工业标准。
性能是LP64位系统的一个主要卖点,虽然在应用程序中过度使用64位数据会造成非常大的内存开销。
可移植性,因为我们已经积累了相当多的成功的移植经验,所以可以很容易从目前的32位工业应用过渡到新的平台下。
所有这些,加上在64位环境可以支持C语言的所有原生数据类型,所有证据都表明LP64是最佳的选择。
相关文章推荐
- 64位编程模型:为什么要使用LP64(二)
- 64位编程模型:为什么要使用LP64(一)
- 一篇博客:分类模型的 Loss 为什么使用 cross entropy 而不是 classification error 或 squared error
- MongoDB中MapReduce编程模型使用实例
- 黑马程序员-- 高级网络编程 什么是泛型?泛型的定义?泛型如何使用?为什么要使用泛型?
- 【Spark亚太研究院系列丛书】Spark实战高手之路-第3章Spark架构设计与编程模型第1节:为什么Spark是大数据必然的现在和未来?(2)
- 为什么交叉熵损失可以提高具有sigmoid和softmax输出的模型的性能,而使用均方误差损失则会存在很多问题
- Linux网络编程之多进程模型编程与一个使用进程池实现的CGI服务器
- 64位VS2012+64位matlab R2010b和32位VS2012+32位matlab R2010b 使用matlab engine实现混合编程配置
- Android驱动开发【NDK模型】———为什么使用NDK
- QThread多线程编程经典案例分析(三种方法,解释了为什么使用moveToThread的根本原因,即为了避免调用QThread::exec() )
- Java并发编程笔记 使用阻塞队列实现生产者-消费者模型
- 使用 WCF REST 编程模型创建接受任意数据的服务
- 为什么 LR 模型要使用 sigmoid 函数,背后的数学原理是什么?
- 异步编程模型--使用 IAsyncResult 对象
- 网络编程基础:使用SELECT模型
- 读书笔记 - .net2.0 异步编程模型: 使用 IAsyncResult 调用异步方法
- 基于UDP的C/S网络编程模型(使用sendto和recvfrom函数)
- WSAEventselect编程模型使用步骤总结
- java断言的使用和契约式设计编程模型简介