Blackrose's Blog Blackrose's Blog

Mac OS X的内核——从32位到64位

in growth-logread (241) 文章转载请注明来源!

本文转载自Weiphone论坛,作者fantacyleo(weiphone's id)。遵循CC版权协议。原文链接

自从标配4G内存的笔记本面市以来,我就非常关心预装操作系统是32位还是64位的,因为虽然理论上32位Win可以用到4G内存,但由于一部分内存要给系统和其他硬件设备预留,用户可见的内存并没有4G,大概只有2-3.5G的样子,而64位的windows可以用到3.8G以上(还有一部分应该是集显占用了)。不过后来我了解到,在目前windows的生态环境下,为了大内存而选择64位系统可能并不明智,因为大量为Win开发的软件都还停留在32位模式阶段,虽然64位win为32位应用程序建立了一个从文件系统到运行时环境的完全、彻底、独立的32位模式以达到兼容的目的,但这是以牺牲性能为代价的,并且不能彻底解决问题。从文件系统来说,64位win有两个Program Files文件夹,一个不带后缀,就像我们在32位win上看到的一模一样,用来存放原生的64位APP;另一个带x86后缀,用来存放32位APP。这个倒还好,根据后缀一目了然,诡异的是在C:\Windows文件夹下的三个system文件夹,一个不带任何后缀(C:\Windows\System)是用来兼容更古老的16位APP,这没问题。第二个是存放64位APP的运行时支持文件,可文件夹却被命名为C:\Windows\System32,第三个是存放32位APP的运行时支持文件,文件夹竟然名为C:\Windows\SysWoW64。在为32位软件搭建的虚拟运行环境中,包括了虚拟的CPU(执行32位指令集)、虚拟注册表、虚拟文件系统、虚拟内存空间,32位软件完全不会知道自己是在一台64位架构的电脑上运行(大家在PD模拟器里跑的Win一样不知道自己外面还有个Mac OS!),如果它调用Win的API来获得系统信息,则会被告知电脑的一切都是32位的。32位软件和外部64位环境的一切联系都要先通过这个虚拟环境来中转(参见这个简短的英文说明http://blogs.msdn.com/b/oldnewthing/archive/2008/12/22/9244582.aspx,或这个来自MSDN的更详细的中文说明http://technet.microsoft.com/zh-tw/library/dd180732),从而造成运行效率的损失。在遍地是32位APP的当下,选择64位Win并不能让我们充分享受64位的好处。

理论上来说,64位架构的电脑要比32位架构的电脑速度更快。这里我不扯很多技术问题,就拿乔帮主当年的一个演示视频来说明(好消息,这个视频youku上就有,不用翻GFW了)。在这个视频里,帮主分别用32位模式和64位模式载入一幅美国国会图书馆的照片。这张照片有4G之大,3200032000约10亿像素。接下来,帮主开始调整两张照片的亮度,于是CPU就要开始从内存读照片信息,调整亮度后再返回给内存。64位模式可以访问最多161000000TB的内存,轻而易举就可以把4G大小的照片全部读入内存,因此调整亮度过程中发生的只有CPU和内存间的数据交换,CPU的占用率基本保持恒定。而32位模式理论上最多访问4G内存,实际还达不到,只能将图片信息分次从硬盘读入内存,因此调整亮度过程中还要发生硬盘和内存的数据交换,此时CPU就处于闲置状态,而当CPU和内存交换数据时,CPU又开始忙碌,这导致CPU占用率持续波动,且渲染速度慢于64位模式。

要充分利用64位技术的优势,我们必须有64位的CPU、64位的操作系统和原生的64位APP(当然,还要有大于4G的内存,但在这里内存是个很被动的部分,它本身不知道什么32位、64位的,只是等着别的硬件来使用它。所以我就不提它了),缺一不可。尽管IBM在1961年就造出了能处理64位二进制指令的电脑,但那只是用于超级电脑领域的“王谢堂前燕”,离个人电脑的“寻常百姓家”还有很长的路要飞。在这条路上,Intel错失先机,他们忙着与HP合作搞64位的服务器CPU,这个名为Itanium的CPU系列与Intel在PC上的x86CPU不兼容,结果AMD抢先推出与x86架构兼容的x86-64,后改称AMD64(http://tech.sina.com.cn/h/2007-12-05/10581893688.shtml)。由于Wintel联盟的存在,Intel不出PC用的64位CPU,广大Wintel用户就只能干等。结果又被IBM-APPLE抢先发布世界上第一台64位个人电脑——PowerMac G5。到了2004年,Intel开始在其Prescott系列CPU上使用x86-64技术(其实就是照抄AMD的),并在酷睿系列发布后改名为Intel64,我们现在用的Intel CPU也都是基于它的(http://tech.sina.com.cn/h/2007-12-05/10581893691.shtml)。这里顺带一提,x86-64是一个向下兼容16位和32位APP的技术,并非真正的64位架构,这个兼容货的出现也是Wintel联盟独霸PC市场的必然结果,巨大的市场份额使得AMD和Intel不可能完全抛弃x86用户另起炉灶。而完全不兼容x86的Itanium是一个纯粹的64位架构,只是兼容性问题阻碍了它迈入PC的脚步。

这是2005年升级版的powermacg5机箱内部,可以搭载两个PowerPC G5处理器:

处理器64位化之后,操作系统和APP也要跟上。Win在这里犯了难,因为它的市场实在太庞大了,无数的PC厂商和软件开发者围绕在它身边,牵一发而动全身。微软做了两件事。一是搞32、64两种版本的windows,二是他们在64位Win中搞出了第一段中所描述的32位兼容模式。但这32位兼容模式也不是万能的,比如64位win中的IE就还是32位的,因为Win不允许一个应用程序中同时出现32位和64位的代码,为IE开发的一些插件仍然是32位的,没法和64位IE混合运行。还有驱动程序,必须和底层硬件直接打交道,也没法在32位兼容模式中运行。不过,一般的APP在32位兼容模式下是没有什么大问题的,有庞大的用户群拖着,又这么个32位兼容模式惯着,Win平台向64位的转变肯定是一个漫长的过程。而苹果的64位化之路较win来说就轻松多了。一是用户少,震动小;二是产品线单一,一人吃饱全家不饿。三是苹果采用了Universal Binary技术。第四章中我曾经提到过该技术,现在再来举例子详细说一下,这个例子参考了http://techsingular.net/?p=480

假设一个APP由一个可执行文件(二进制代码组成,受32or64位体系的影响)和一个纯文本格式的数据文件(平台无关,不受32or64位影响)构成。现在我们考虑将OS从32位迁移到64位。第一种办法就是在64位OS中弄一个模拟器跑32位程序,就像64位win那样。Mac OS X在向Intel平台迁移过程中也用过一个模拟器叫Rosetta(见第四章)。模拟器的优点就是程序完全不用改动,完全没有冗余代码,代价就是执行起来速度慢。第二种办法就是对32位和64位系统分别提供一套软件,每套软件都由两个文件组成(可执行文件+数据)。这种办法在APP执行上没有效率损失,但软件用户要根据自己的电脑配置买不同版本的软件,不够傻瓜,如果他们同时拥有两个平台的电脑,那么就要买2份软件,其中的数据文件部分完全相同,这就造成了重复。第三种办法是只针对不同平台制作不同的可执行文件,而共享同一份平台无关的数据文件。这种方式大大减少了冗余,但是要求APP的安装程序要智能,根据不同平台安装不同版本的可执行文件。对于用户来说,由于不同APP实现智能安装的方式不同,每装一个新软件都要再去熟悉这个软件的安装特点,而且在不同平台上装的软件版本仍然不同,无法互相copy,无法实现Mac OS经典的单文件APP。在Mac OS X中,大多数应用程序呈现在用户面前的都只有一个文件。如果你在APP上点右键,选择“显示包内容”就可以看到其复杂的内部结构,这种方式类似于计算机科学中的“抽象”,它的目的是对无关人员隐藏具体的实现细节。

单文件APP:

显示包内容:

第四种方式就是Universal Binary。它在任何平台上都只安装2个文件,即可执行文件+数据,但是在可执行文件中同时包含32位和64位的代码,操作系统根据需要调用不同代码。这种方式既方便开发者也方便用户。苹果从Xcode2.1开始提供编译成Universal Binary的功能,开发者可以参阅Universal Binary Programming Guidelines。当然,也不是所有程序用Xcode这么轻松编译一下就ok了。根据Universal Binary Programming Guidelines,如果一个程序利用的基本上是GUI层的功能,那么编译一下就差不多OK了。但如果程序大量利用了系统底层的功能,那么对不起,你的麻烦大了。比如Office for mac直到2008年才支持Universal Binary。用户就更轻松了,他们完全不用知道软件内部发生了什么变化,跟原来一样买、一样装、一样用就可以了。当然了,这种方式也有缺点,比如我用64位系统,但安装好的软件中依然包含32位代码,这对我来说是多余的。同样,一个32位系统的用户会发现安装好的软件中有他不需要的64位代码。

安抚了开发者和消费者,苹果就要全力完成操作系统的64位化了,和转向Intel平台相比,这一步苹果走得依然不痛苦,但却漫长,它花了苹果6年时间。

Mac OS X64位化的第一步就是刚才提到过的PowerMac G5,随同G5发售的Mac OS X Panther(10.3)内核开始支持64位运算,内核能够访问64位内存地址,但普通APP依然只能看到32位内存空间(参见:Mac OS X背后的故事 九(上))。

2005年发布的10.4 Tiger引入了64位指针,让每一个APP运行的进程都可以访问64位内存地址。同时,Tiger开启了第一个64位的编程支持,这就是Unix层的libSystem库的64位化,这个库包含了文件I/O、网络等基础功能,基本上可以让开发者编写64位的非GUI程序了。但是GUI编程仍然只能在32位下进行(http://arstechnica.com/apple/2005/04/macosx-10-4/4/)。当然,对于当时的大多数程序来说,64位化的需求并不迫切,谁会没事写个64位的通讯录程序呢,难道你认识全地球的人?但如果是Matlab、Maple这种科学计算程序,那就麻烦了,GUI界面是32位写的,为了计算的速度和精度又必须去和底层的64位库打交道。2005年也是苹果宣布转向Intel的年份(参见第四章),帮助开发者和用户平稳过渡的Universal Binary正式登场,并于2006年开始内置于运行在Intel CPU的Tiger中。Intel CPU的到来倒是给了Mac开发者投奔64位世界一个很好的理由。简单来说,64位Intel CPU不但能处理64位指令,而且其中能处理64位指令的元器件数量也比32位CPU多(用专业术语来说,64位Intel CPU的寄存器是64位的,而且寄存器数量也比32位 CPU多)。

2007年,姗姗来迟的10.5 Leopard将GUI APP带入了64位。同时,非GUI层的全部编程库也完成了64位迁移(Mac OS X背后的故事 九(上))。当然,对32位的支持仍然保留。随着GUI层的64位化,苹果也开始向另一个历史遗留问题开刀,那就是为了向下兼容Mac OS 9而建立的Carbon编程支持库。HIToolBox是Carbon中为C语言写的GUI库,2006年WWDC大会上,苹果指出HIToolBox将和Mac OS X原生的GUI库Cocoa整合http://origin.arstechnica.com/reviews/os/mac-os-x-10-5.media/carbon-future.mp3,而在2007年的WWDC大会上苹果宣布Carbon的整个GUI部分都将不会进入64位时代,Carbon被彻底判了死刑,所以Leopard中只有Cocoa写的GUI可以是64位的。一石激起千层浪,围绕Carbon的存废也有些故事,我会留待本系列的GUI篇和开发工具篇时再讲。

Leopard之后,Mac OS X离64位化只有一步之遥:内核的彻底64位化。这个任务由2009年发布的10.6 Snow Leopard来完成,它也是我接触的第一个Mac OS X版本。为了照顾那些还停留在32位时代的驱动程序,SL默认以32位模式的内核启动,如果你想切换到64位模式,可以在电脑启动时同时按住6和4两个键。这个版本很有趣,它的前辈Leopard有300项新功能:

而它却没有任何新功能:

尽管如此,它肩负的使命却十分重大。另外,SL还彻底与PowerPC决裂,只有运行在Intel CPU上的苹果电脑才能装它(我是说正常情况下,对Geek来说不是问题)

10.7 Lion和10.8 Mountain Lion在32位到64位的转变中就没那么重要了,他们只不过是在主要的第三方开发者都已经做好准备的情况下,对32位程序关上最后的大门。Lion的内核默认以64位启动,而ML则在内核中彻底移除了对32位程序的支持(10.8的XNU代码还没有放出来,我不知道ML的XNU版本号是多少),所以那些早期依然有32位驱动程序的苹果电脑就被排斥在ML的支持升级范围之列,不过这难不倒Geek们,他们仍然有办法在老电脑上安装ML。不知道有没有童鞋尝试过并成功了呢?不过,即使这种方法能装好ML,估计也没法运行,因为内核中已经没有任何32位代码了。

文章二维码

扫描二维码,在手机上阅读!

mac
发表新评论
博客已萌萌哒运行
© 2018 由 Typecho 强力驱动.Theme by Yodu
前篇 后篇
雷姆
拉姆