大森林论坛 int

时间:2019-06-12         浏览次数
c?5113.1101.0143.8哈?尔?滨101.人又容易为安逸所累,总是看着这美丽的风景,SUN 最初开发 Java 的唯一目的,这个创举,一个叫做 PC(Program Counter),2019彩色正版老鼠报断,其中讲了生物和机器的反馈。
高的时候曾经超过50%,所以可以随意改掉。这些chunkserver可能被各机架的几百个客户端访问。存储在master的本地磁盘并且复制到远程机器。"那边有点小问题,你会感受到非常高的重力加速度"在飞船持续上升过程中"然后在太空中有很长一段时间是零重力"在你重回引力的作用之前。而中国现在是35%左右。谈到要让市场在资源配置中起决定性作用。我把电脑放在床前,设置属性。
新增数据可以做到无竞争(刚才5.至于你是用它来处理大文件、存储增量数据、打造一个NoSQL、还是解决海量小文件,融易富配资交易软件,高级语言编程领域也发生了一件大事,他们相信大脑的结构和工作机理决定了智能, , ; asm or __attribute__ before x而优雅的 Clang 则用彩色的提示告诉你是不是拼错了并给出可能的变量名:tc:2:1: error: unknown type name int64; did you mean int64_tint64 x;^~~~~int64_t更多的例子可以参考 http://blogllvmorg/2010/04/amazing-feats-of-clang-error-recoveryhtml 而同时又因为 Clang 是高度模块化的一个前端很容易实现代码的高度重用所以比如 Xcode 40 的集成编程环境就使用 Clang 的模块来实现代码的自动加亮、代码出错的提示和自动的代码补全开发者使用 Xcode 40 以后的版本可以极大地提高编程效率尽可能地降低编译错误的发生率支持 C++ 也是 Clang 的一项重要使命C++ 是一门非常复杂的语言大多编译器(如 GCC、MSVC)用了十多年甚至二十多年来完善对 C++ 的支持但效果依然不很理想Clang 的 C++ 支持却一直如火如荼地展开着2010 年 2 月 4 日Clang 已经成熟到能自举(即使用 Clang 编译 Clang到我发稿时LLVM 30 发布已完整支持所有 ISO C++ 标准以及大部分C++ 0x 的新特性这对于一个短短几年的全新项目来说是非常不易的得益于本身健壮的架构和 Apple 的大力支持Clang 越来越全能从 FreeBSD到 Linux Kernel 从 Boost到 Java 虚拟机 Clang 支持的项目越来越多Apple 的 Mac OS X 以及 iOS 也成了 Clang 和 LLVM 的主要试验场106 时代很多需要高效运行的程序比如 OpenSSL 和 Hotspot 就由 LLVM-GCC 编译来加速的而 106 时代的 Xcode 32 诸多图形界面开发程序如 Xcode、Interface Builder 等皆由 Clang 编译到了 Mac OS X 107整个系统的的代码都由 Clang 或 LLVM-GCC 编译【注:http://llvmorg/Usershtml】LLVM 周边工具由于受到 Clang 项目的威逼GCC 也不得不软下来让自己变得稍微模块化一些推出插件的支持而 LLVM 项目则顺水推舟索性废掉了出道时就一直作为看家本领的 LLVM-GCC改为一个 GCC 的插件 DragonEgg Apple 也于 Xcode 42 彻底抛弃了 GCC 工具链而 Clang 的一个重要衍生项目则是静态分析工具能够通过自动分折程序的逻辑在编译时就找出程序可能的 bug在 Mac OS X 106 时静态分析被集成进 Xcode 32帮助用户查找自己犯下的错误其中一个功能就是告诉用户内存管理的 Bug比如 alloc 了一个物件却忘记使用 release 回收这已经是一项很可怕的技术而 Apple 自己一定使用它来发现并改正 Mac OS X 整个系统各层面的问题但许多开发者还不满足既然你能发现我漏写了 release你为什么不能帮我自动加上呢于是 ARC 被集成进 Clang发生了文章开头开发者们的惊愕从来没有人觉得这件事是可以做成的除 LLVM 核心和 Clang 以外LLVM 还包括一些重要的子项目比如一个原生支持调试多线程程序的调试器 LLDB和一个 C++ 的标准库 libstdc++这些项目由于是从零重写的因此要比先前的很多项目站得更高比如先前 GNU、Apache、STLport 等 C++ 标准库在设计时C++0x 标准还未公布所以大多不支持这些新标准或者需要通过一些肮脏的改动才能支持而 libstdc++ 则原生支持C++0x而且在现代架构上这些项目能动用多核把事情处理得更好不单单是 Apple诸多的项目和编程语言都从 LLVM 里取得了关键性的技术Haskell 语言编译器 GHC 使用 LLVM 作为后端实现了高质量的代码编译很多动态语言实现也使用 LLVM 作为运行时的编译工具较著名的有 Google 的 Unladen Swallow【注:Python 实现后夭折】、PyPy【注:Python 实现】以及 MacRuby【注:Ruby 实现】例如 MacRuby 后端改为 LLVM 后速度不但有了显著的提高更是支持 Grand Central Dispatch 来实现高度的并行运行由于 LLVM 高度的模块化很方便重用其中的组件来作为一个实现的重要组成部分因此类似的项目会越来越多LLVM 的成熟也给其他痛恨 GCC 的开发项目出了一口恶气其中最重要的恐怕是以 FreeBSD 为代表的 BSD 社区BSD 社区和 Apple 的联系一向很紧密而且由于代码相似很多 Apple 的技术如 Grand Central Dispatch 也是最早移植到 FreeBSD 上BSD 社区很早就在找 GCC 的替代品无奈大多都很差(如 Portable C Compiler 产生的代码质量和 GCC 不能同日而语)一方面是因为不满意 GCC 的代码品质【注:BSD 代码整体要比 GNU 的高一些GNU 代码永无休止地出现各种严重的安全问题】更重要的是协议问题BSD 开发者有洁癖的居多大多都不喜欢 GPL 代码尤其是 GPL 协议第三版发布时和 FreeBSD 的协议甚至是冲突的这也正是为什么 FreeBSD 中包含的 GNU 的 C++ 运行库还是 2007 年以 GPLv2 发布的老版本而不是支持C++0x 的但依 GPLv3 协议发布的新版本因此历时两年的开发后2012年初发布的 FreeBSD 90 中Clang 被加入到 FreeBSD 的基础系统 但这只是第一步因为 FreeBSD 中依然使用 GNU 的 C++ STL 库、C++ 运行库、GDB 调试器、libgcc/libgcc_s 编译库都是和编译相关的重要底层技术先前全被 GNU 垄断而现在 LLVM 子项目 lldb、libstdc++、compiler-rt 等项目的出现使 BSD 社区有机会向 GNU 说"不"因此一个把 GNU 组件移出 FreeBSD 的计划被构想出来并完成了很大一部分编写过《Cocoa Programming Developers Handbook》的著名 Objective-C 牛人 David Chisnall 也被吸取入 FreeBSD 开发组完成这个计划的关键部分 估计在 FreeBSD 10 发布时将不再包含 GNU 代码LLVM 在短短五年内取得的快速发展充分反映了 Apple 对于产品技术的远见和处理争端的决心和手腕并一跃成为最领先的开源软件技术而 Chris Lattner 在 2010 年也赢得了他应有的荣誉Programming Languages Software Award(程序设计语言软件奖)Mac OS X 背后的故事(九)半导体的丰收半导体的丰收(上)在美国宾夕法尼亚州的东部有一个风景秀美的城市叫费城在这个城市产生了一系列改变世界的奇迹:第一个三权分立的国家美立坚合众国就在第五街的路口诞生;举世著名的费城交响乐团1900年在市中心的 Academy of Music 奏响了他们的第一个音符而写这篇文章时我正坐在三十四街的宾夕法尼亚大学计算机系的一楼实验室面前摆放着世界上第一台电子计算机ENIAC1946年 2 月 14 日ENIAC 问世每秒可运行 5000 次加法运算或 500 次乘法运算面积达 170 平方米重约 30 吨拉开了运算机处理器革命的序幕这场革命是各处理器厂商长达数十年的竞赛而摩尔定律从一开始就准确地猜测了这场比赛的走势根据摩尔定律同样价格的集成电路上可容纳的晶体管数目每隔约 18 个月便会增加一倍性能也将提升一倍但事实上并无法用老路子来保持这个增长速度因为会遇到包括能耗、散热等各种技术瓶颈所以每隔几年就会有用来绕过这些瓶颈的新一代产品推出如采用超纯量(superscala)、指令管线化、快取等这些技术通过一定程度的高效并行来挖掘计算机处理器的速度所能达到的高度以促使用户更新换代世界上第一台计算机 ENIAC1946年 2 月 14 日诞生于宾夕法尼亚大学和 66 年前的 ENIAC 相比2019-06-02 的处理器已有了质的飞越而 21 世纪的前十年我们更是见证了个人计算机处理器的三次重大革命64位处理器、多核心和高效图形处理器在个人电脑出现在这样的背景下乔布斯在 2008 年 WWDC(苹果全球开发者大会)上宣布下一代 Mac 操作系统 Mac OS X 106 将被命名为 Snow Leopard(雪豹)来适应硬件架构的革新就在那天下午Bertrand Serlet 在一场开发者内部讲座上透露和先前两个发行版包含大量的新功能(104 Tiger 包含 150 个新功能105 Leopard 包含 300 个新功能)不同Snow Leopard 不含任何新功能仅是对 Leopard 中诸多技术的重大更新以使其在现代架构上更稳定、高效 在这十年的最后一年2009 年 8 月 28 日苹果发布了 Mac OS X 106 来有效地支持这三项技术而本文将为读者介绍其对应的三项软件技术64位架构、Grand Central Dispatch以及 OpenCL 其他 Mac OS X 106 技术更新如全新的 QuickTime X 和跳票的 ZFS有着更复杂的历史背景(以后再为读者介绍)64 位架构出现的缘由前文提到根据摩尔定律同样价格的集成电路上可容纳的晶体管数目约每隔 18 个月便会增加一倍性能也将提升一倍事实上存储器的容量增长可能更快每过 15 个月就会翻一番有了更快更强的电脑可能会让数值计算的科学家们喜出望外但对普通大众来说摩尔定律给普通消费者一个假象如果你觉得 1000 美元的苹果电脑太贵那等上 18 个月就可以用 500 美元买到同样的电脑十年前你在用电脑写 Word 文档十年后你还在用电脑写 Word 文档反正计算机不是耗材一台电脑只要不坏就不用去买新的计算机产业的巨头们自然知道摩尔定律对他们造成的致命打击因此一个阴谋被以 Intel 和 Microsoft 为首的巨头们构想出来Intel 负责把硬件越做越快而 Microsoft 则负责把自己的软件越做越臃肿、越做越慢至于你信不信反正我是信的因此使用软件、服务等直接促进计算机产业的消费使得计算机产业走上可连续发展的道路这在计算机产业被称为 Andy-Bill 定律分别以 Intel 和 Microsoft 总裁的名字命名当然软件公司未必真心欺诈消费者有意把软件做大做慢为了实现一个新功能软件势必会比原先庞大但现代软件的速度、大小和其增加的功能并不成比例比如对最终用户来讲Windows Vista 到底比 Windows XP 多了多少功能呢可能只有 20%~30%Word 2007 对比 Word 2003 多了多少功能呢可能也只有 20%~30%但 Windows Vista、Word 2007 占用的 CPU、内存、磁盘空间却比 Windows XP 和 Word 2003 翻了几番究其原因为了能赶快把新功能带给用户我们不惜使用更方便但低效的编程语言(NET、Java 等依靠虚拟机的语言就要比 C 慢许多Python 等动态语言比 C 慢的不是一星半点)、快速开发(我们原先处理一个大文本先分块一点一点读到内存中然后把处理完的部分写回磁盘清空内存;而现在直接把它全读进来处理开发方便执行也快)而用户必须为这些新功能买不成比例的单64 位就是在这个背景下迅速走入寻常百姓家的程序占用越来越多的内存而 32 位的寻址空间已不能满足软件运行的需要了64位 CPU 是指 CPU 内部的通用寄存器的宽度为 64bit支持整数的 64bit 宽度的算术与逻辑运算早在 1960 年代64位架构便已存在于当时的超级电脑且早在 1990 年代就有以 RISC 为基础的工作站和服务器2003 年才以 x86-64 和 64 位元 PowerPC 处理器架构(在此之前是 32 位元)的形式引入到个人电脑领域从 32 位元到 64 位元架构的改变是一个根本的改变因为大多数操作系统必须进行全面性修改以取得新架构的优点成功的迁移苹果向 64 位处理器的迁移花了整整 6 年时间远长于该公司其他技术的迁移向 Intel 的迁移仅用了一年时间从经典 Mac OS 到 Mac OS X 也仅用了三年时间总而言之这场迁移是非常成功的:一方面用户基本无痛苦老的 32 位程序在目前最新版的 Mac OS X Lion 中依然可以完全兼容地执行;另一方面对开发者而言基本只需做微小的调整重新编译程序而且若干技术如 Universal Binary使他们发布程序非常方便当然对于某些大量使用过时技术的公司如 Adobe 和 Microsoft这场迁移则要折腾得多这场迁移整整用了四个发行版的时间(103 至 106)不同于 Windows 或 LinuxMac OS X 对 64 位的迁移自下而上再自上而下先是内核扩展逐步上升至 Unix 空间然后上升至用户界面再上升至整个应用程序生态最后完成内核的迁移要提醒读者的是Mac OS X 的 32 位和 64 位内核空间与用户空间的分配和实现和 Windows 存在本质的区别但在本期介绍中我们尽可能少地把 Mac OS X 的 64 位迁移和 Windows 进行比较不拘泥于技术细节对此区别有爱好的读者请移步 AppleInsider 的系列专题2003 年苹果发布了其第一款 64 位计算机工作站 Power Mac G5同期发布的 Mac OS X 103 也因此增加了非常简单的 64 位支持于是 XNU 内核开始支持 64 位的寄存器和整数计算但对于用户空间而言程序可见的地址依然是 32 位的程序当然可以使用大于 4GB 的内存(Power Mac G5 最高可达 8GB 寻址空间)但这要求程序手动地在两个 32 位内存空间中来回转换两年后苹果发布了当时最成功的 Mac OS X 发行版 Mac OS X 104 Tiger10 4 的内核是革命性的除了增加对内核并行多线程的支持它把用户空间可见的地址空间扩展到了 64 位因此理论上用户程序可以以 64 位方式执行当然在这个时期几乎系统内的所有程序哪怕是内核依然是 32 位的系统中唯一带的 64 位二进制文件是名为 libSystemdylib 的系统库它是 Mac OS X 上对 C 标准和 POSIX 标准的支持库由 libc、libinfo、libkvm、libm 和 libpthread 五部分组成但这仅有的 libSystemdylib 理论上就能让所有仅使用 C 标准库和 POSIX 标准库的程序以 64 位模式运行当时用户对 64 位的需求较少主要限于科学计算或图形处理等需要大数组的领域因此104 能较好地满足这部分用户的需求但如果程序需要调用除 BSD Unix 以外的系统调用比如想用 Cocoa 来画图形界面那么该程序仅能以 32 位方式运行了对于一些需要 64 位寻址空间的科学计算程序比如 Mathematica就需要采用一些比较麻烦的做法:用一个进程调用 32 位的 Cocoa 画图形界面用另一个进程调用 64 位的 libSystem 来进行运算和 Unix 系统调用并用 Unix 管道或进程间通信的方式管理两个进程间的输入/输出苹果在 Mac OS X 104 发布同期的另一项重要决策是向 Intel 平台 x86 及 x86_64架构的迁移为了帮助开发者和用户顺利迁移苹果正式公布了 Universal BinaryUniversal Binary 技术是 Mach-O 二进制文件早就具有的特性只是在这个场合作为一个商业词汇进行宣传NeXT 时代 NeXTSTEP 操作系统就支持许多种不同的硬件架构自然可以要求开发者对每个平台发布一个独立的版本但这样的分发模式很麻烦消费者也需要搞清到底购买哪种平台的软件因此 NeXT 的 Mach 内核所支持的 Mach-O 二进制文件格式引入了一种叫 fat binary 的特性说白了就是在一个平台架构上分别交叉编译所有平台的二进制格式文件然后把每个文件都打包成一个文件Universal Binary 就是指同时打包 Intel 平台和 PowerPC 平台的二进制文件Mac OS X 104 最终支持四个平台的 BSD 系统调用32 位 Power PC、64 位 PowerPC、32 位 x86 和 64 位 x86_64作为最终用户无须搞清这些区别因为使用 Universal Binary 技术买回来的软件直接会解出相应平台程序的二进制文件并执行这是苹果很成功的一步不像 Windows 系统中要用不同的路径(\Windows\System、\Windows\System32、\Windows\System64)分别存放不同架构的二进制库并且用户还需在 32 位版和 64 位版之间犹豫不决Mac OS X 105 Leopard 经过一系列跳票终于在 2007 年末发布跳票主要原因是当时苹果投入了大量人力和物力去做 iPhone以至于 105 跳票了整整一年105 包含了约 300 项新功能而最重要的一项是苹果把对 64 位的支持带入了 Cocoa 层面因此几乎系统中所有的库都有四个平台的版本在 WWDC 上乔布斯亲自向与会者介绍迁移到 64 位的好处而能使用更大的内存自然是一项重要优势程序可以申请更大的内存把所有数据一并读入内存中操作而无须分块后来来回回地在内存和磁盘搬运数据另外对 Intel 平台来说x86 架构只有 8 个寄存器而 x86_64 平台有 16 个寄存器这也就意味着对该平台来说只要重新编译程序程序就能自由调度比原先翻倍的寄存器数量而无须快取或在内存中来回查找和读写根据粗略估算一般涉及大量数值计算的程序会加快一倍所以他很开心地劝说所有的开发者都迁移到 64 位架构历时整整 6 年时间苹果完成了向 64 位处理器的迁移同时这也给苹果提供了良好的清理门户的机会清理过时的技术和 API彻底的清理同时苹果做出了一个大胆的举动Carbon 框架并未出现在这次迁移中Carbon 是 Mac OS X 诞生之初为了帮助 Mac OS 开发者把老程序迁移到新的 Mac OS X 操作系统上所提出的一个兼容 API这套 API 长得很像经典 Mac OS 的 API但能够得到 Mac OS X 平台提供的一切新特性Adobe、Microsoft 等都是通过 Carbon 把它们经典的 Mac OS 程序移植到 Mac OS X 上的苹果的本意是期望开发者用 Carbon 迁移老程序用 Cocoa 开发新程序但在 Carbon 诞生之初其受关注度远大于 Cocoa据 TeXShop 开发者 Dick Koch 回忆在 Mac OS X 刚诞生的开发者大会上Carbon 讲座的教室挤满了人而 Cocoa 相关的讲座上听者无几保护两套雷同的 API 的代价自然很高所以砍掉一个是大势所趋Carbon 和 Java 的热度甚至一度让苹果产生索性把 Cocoa 或 Objective-C 砍掉的想法大量苹果自家的程序如 Finder、iTunes、Final Cut、QuickTime 等也都是用 Carbon 写成的不过在此后由于大量涌现在 Mac OS X 平台上的新程序都是 Cocoa 写的导致 Cocoa 技术不断走高2007年的 iPhone 也完全依赖于 Objective-C 和 Cocoa 的一个裁剪版 Cocoa Touch因此在 WWDC 2006 上苹果在 Mas OS X Leopard 105 的开发预览版中包含了测试版本的 64 位 Carbon 库甚至还有讲座教如何开发 64 位的 Carbon 程序但苹果却在 2007 年告诉 Carbon 开发者他们的程序将不可能再被编译成 64 位要做到这点必需先把程序用 Cocoa 重写这个突然的决定激怒了很多开发者特别是以 Microsoft 和 Adobe 这些巨头为代表的公司Adobe 全套的 Creative Suite 和 Microsoft 全套的 Microsoft Office 是很多苹果用户必备的软件数百万行代码全是用 Carbon 写的所以直到2019-06-02 除了 Adobe Photoshop 等少数程序终于在 2010 年全面移植到 Cocoa 后做出了 64 位版其他大部分程序依然停留在 Carbon 的 32 位模式苹果也花了很长时间来重写 Finder、FinalCut、iTunes、QuickTime 等程序或技术耗费了大量精力当 Adobe 发布 64 位的 Lightroom 20 时苹果还在手忙脚乱地重写 Aperture不过公平地讲长痛不如短痛砍掉对 Carbon 的支持能够使苹果把更多精力放在该做的事上也使得 Mac OS X 的结构更简洁并且事实上64 位的迁移为苹果提供一个砍去老 API 的机遇哪怕对 Cocoa 也是一方面Cocoa 框架中很多类不是使用类似 Carbon 的 API就是依赖于用 Carbon 实现(注意和传统观念不同Carbon 和 Cocoa 在早期 Mac OS X 上是相互依赖的比如菜单 NSMenu 就使用了 Carbon 的菜单管理器)这些 API 在 64 位得到了彻底清理QuickTime 相关的 C 接口全被砍去Cocoa 经过很长时间的发展自然也保留了很多过时的 API 以保证和原先的产品兼容而这次机会给苹果足够的理由彻底推翻原先的设计在 Mac OS X 105 中 Objective-C 的运行库 libobjc 更新到 20提供了全新的并发、反常处理、自动内存回收、属性(property)等新机制其中很多新特性只供64位享用同时所有 int 都被改为 NSIntegerCore Graphics 中的 float 都改为 CGFloat以保持 API 统一这些都是 64 位架构上的改动因此 64 位迁移给苹果一个很好的清理门户的机会作为相反的例子这次清理也有不彻底的地方比如从老版 Mac OS 中混进来的 Keychain 库甚至具有 Pascal 风格的 API由于没有替代品它也得到了 64 位的更新所以类似 keychain 这样的库成了现在 Mac OS X 程序员的噩梦我每次用到 Keychain 都有痛不欲生的感觉而 2009 年发布的 Mac OS X 106 Snow Leopard 则是对 64 位真正完整的支持Unix 层虽然 104 就提供了 64 位的 libSystem但所有的 Unix 用户空间工具包括 ls、Python 等以及 Xcode 中的 gcc也都是以 32 位二进制的模式发布的图形界面层在 105 Leopard 中虽然整个系统的库都迁移到 64 位以 32 位和 64 位的混合模式发布但用户应用程序依然是 32 位的只有 Chess、Java、Xcode 套件等少数程序以 64 位编译但在 106 中基本所有的应用程序都被迁移到 64 位不管是 Safari、Mail、Dock还是 TextEdit当然各种 Unix 工具包括 LLVM、GCC 等也都以 64 位的模式发布106 只有四个 Carbon 程序(Front Row、iTunes、DVD Player 以及 Grapher)未得到 64 位升级【2009 年查阅现页面已更新至 107】其中 Front Row 在 Mac OS X 107 Lion 中被砍掉 iTunes 在 107 发布时依然以 32 位模式发布在 2011 年末的更新中才迁至 64 位为了使应用支持 64 位苹果不遗余力地改写了大量代码Snow Leopard 中最重要的重写当属 Finder这个程序自 Mac OS X 发布以来就一直是一个 Carbon 程序并且苹果一直不停地改进它以展现 Carbon无所不能但自从 105 时代苹果下决心砍掉 Carbon 后该程序被完整地重写新的 Finder 和 Carbon 版的 Finder 看上去并没有太大差别但 Finder 使用 Cocoa 重写后不仅速度更快而且增加了许多 Cocoa 新特性比如加入了更多的 Core Animation 特效来平滑过渡动画总之虽然苹果在 106 期间没有提供太多新功能但这样大规模的重写为今后代码的可维护性奠定了良好的基础Mac OS X 106 发行版也完成了 64 位化的最后一步内核的 64 位化半导体的丰收(中)经过 6 年时间4 个发行版苹果终于完成了向 64 位的迁移并随着 Snow Leopard 的发布推出了解决并行编程问题的 Grand Central Dispatch(简称 GCD)技术释放了多核系统的潜力和 105 一样在 106 Snow Leopard 中苹果连续利用 64 位的迁移砍掉了诸多老技术很多新技术仅以 64 位的模式被支持例如重写的 QuickTime X 框架虽然 QuickTime X 应用程序以 32 位和 64 位的模式发布但其 API 仅暴露给 64 位另一个例子是 Objective-C 21 的运行库快速 Vtable 调度新的和 C++ 统一的特殊处理模型以及彻底解决对象的 FBI 问题等都仅限 64 位程序使用内核的 64 位化读者应该发现经过这 4 个发行版Mac OS X 自下而上地对整个系统向 64 位迁移103 内核空间提供了 64 位整数运算的支持104 答应程序以 64 位模式运行在用户空间并且提供了 64 位的 libSystem 使得开发者可以开发 64 位的 Unix 程序而 105 中系统所有未废弃的函数库、框架都提供 64 位版本到了 106所有用户空间的程序包括 Unix 层和图型界面层基本都更新到 64 位细心的读者不禁会问那内核是 64 位的吗是的自下而上支持 64 位后106 又从上往下迁移了整个系统中最后一个也是最重要的部分内核内核 64 位化的意义对于 Windows、Linux以及 FreeBSD 等操作系统64位实现的第一步是实现 64 位的内核然而 Mac OS X 却反其道而行主要原因是反正 32 位的内核也能以非模拟、非兼容的方式原生地运行 64 位用户空间程序而内核和与内核动态链接的驱动很少需要用到 64 位的寻址空间(你什么时候见过内核本身使用 4GB 内存)所以该问题可以暂缓但要记住用户空间的内存是由内核管理的虚拟内存、内存分页等机制都是由内核一一实现的一旦在不久的将来随着用户空间的内存占用越来越多虚拟内存的分页比也会不断膨胀比方说一个用户程序使用 4GB 的空间每个分页包含 4KB 的页面那么总共有 1M 个页面因此假设一个页面需要 64B 的 PTE 来记录该页的位置那总共也就需要 64MB 的内核空间来记录这个用户空间程序的虚拟内存不算太多而在不久的将来如果一个 64 位用户程序使用 128GB 的空间则需要 32M 个页面每个页面 64B 的 PTE 会导致 2GB 的内核地址空间来寻址(暂不考虑大分页)32 位的内核就显得非常紧张另外上一期我们也提到 64 位的 Intel 架构提供了比 32 位多一倍的寄存器因此用户空间程序对 64 位内核的系统调用也会更快根据苹果的数据系统调用的响应速度比原先快了 250%而用户空间和内核空间的数据交换也快了 70%因此64位内核要比 32 位内核更快内核完成 64 位迁移虽然在 Mac OS X 106 中苹果提供了 64 位模式运行的内核但在大部分苹果计算机上这个特性并不默认启用其原因是虽然 64 位程序和 32 位程序可以在计算机上同时运行但 64 位的程序只可以加载 64 位的库或插件32位程序只能加载 32 位的库或插件因此如果默认使用 64 位模式启动则诸多第三方的 32 位驱动或内核模块将无法使用当然用户可以通过修改 comappleBootplist、nvram或开机按住 6 和 4强制加载 64 位内核不过苹果并不举荐这样的方式直到 Mac OS X 107 时第三方内核扩展已趋完善大部分的 Mac 才默认使用 64 位内核模式启动苹果用了整整 6 年的时间完成 64 位的迁移在 2009 年 WWDC 的一个讲座上Bertrand Serlet 告诉开发者我们这个 64 位技术的讲座只针对 Mac OS X而 iPhone、iPad 等 iOS 设备由于使用 ARM 平台在可预见的未来可能并不会支持 64 位技术不过两年之后的 2011 年 10 月 27 日ARM v8 发布ARM 正式宣布支持 64 位未来会不会出现基于 ARM 的 Mac或是 64 位的 iPad除了苹果谁知道呢Bertrand Serlet 在 WWDC 2009 上介绍 Snow Leopard 的 64 位和 Grand Central Dispatch 技术GCD(Grand Central Dispatch)来临很长一段时间以来处理器靠更快的运行时钟来获得更高的效率软件开发者无需改动或重新编译他们的代码就能得到摩尔定律许诺他们的好处因为处理器顺序地执行计算机指令新一代的处理器就自动会跑得比原先更快后来每每达到一个技术极限时总有一些聪明的方法绕过这些极限比如超纯量、指令管线化、快取等不是悄无声息地把多条互相独立的指令同时运行就是隐藏掉数据读写的延时GCD 出现的缘由到了 21 世纪能想的办法基本都想尽了现代处理器已经足够并行了也采取了各项优化来不断提升各种预测器的准确率而时钟频率却是不能无限提高的提高时钟频率会极大地增加处理器的产热使得服务器机房或笔记本的散热成为一个头痛的问题同时对于便携设备而言高频也意味着短得多的电池时间因此摩尔定律正在经受重大的考验因此大约在 21 世纪头十年过掉一半时"多核"处理器终于开始跃入普通消费者的视线"多核"顾名思义就是把原先单核的半导体线路复制多份排于同一裸片上每个核相互独立又能彼此通信多核处理器的出现有效缓解了计算机处理器生产商的设计和制造压力从而达到忽悠消费者买更新款产品这一不可告人的目的但这一次技术革新并不如之前那么顺利因为程序并不会自动在多核系统上跑得更快甚至有很多程序每一步都有前后依赖不能高效地并行运行即使能够高效并行的程序也需要大规模改写才能充分利用多核所带来的优势传统的并发编程模式就是学习使用线程和锁这听起来很简单几句话能说明白:把每个任务独立成一个线程;不允许两个线程同时改动某个变量因此得把变量"锁"起来;手动管理线程的先后并发顺序和并发数量让它们平均地占满系统资源;最好系统中只有这个程序在运行否则你精心设计好的线程管理算法往往不能达到原来该有的效果;最后祈祷程序在用户那儿不出问题但是实际操作起来多线程程序的编写要比单线程难上不止一个数量级一方面调用大量内存和数据反复的加解锁本身效率就非常低下;另一个重要原因在于由于多线程程序可能以任意的次序交错执行程序再也无法像顺序执行时那样产生确定的结果多线程程序看似容易编写但难分析、难调试更容易出错即使是最熟练的开发者在茫茫线程和锁之间也会迷失方向且程序的错误在很多时候甚至是不可重现的所以程序员使用线程和锁机制编写并行程序的代价是很高的GCD 就是在这种背景下被苹果提出来的2008年最初提出但未公布细节时很多人怀疑它是 FreeBSD 的 ULE 调度器在 Mac OS X 上的实现ULE 是 FreeBSD 当时最新的内核调度器用来替换掉老一代的 4BSD 调度器当时使 FreeBSD 上跑多线程程序的效率获得了重大的性能提高远高于同期 Linux 和 Solaris 的算法效率但当时我就认为 GCD 依赖 FreeBSD 这项技术的可能性不大因为 Mac OS X 中管理进程和线程主要用的是 Mach 而不是 BSD不过后来证实我只猜对了一半GCD 的实现实际上是依赖于 FreeBSD 的另一项技术 kqueuekqueue 是一个由 FreeBSD 4 时代引入的新功能内核级别地支持消息通信管理GCD 的队列其实就是用 kqueue 实现的GCD 出现的意义在 GCD 中开发者不再管理和创建线程而是将要实现的运算抽象成一个个任务一起扔给操作系统转而让操作系统管理这在计算机科学中被称为线程池管理模式在 GCD 中开发者使用很简单的方式就能描述清应用程序所需执行的任务以及任务之间的相互关联每一个任务在代码中被描述成块(block)然后开发者把一个一个块显式地按顺序扔到队列(queue)中使用块和队列两个抽象的表述开发者无须创建线程也无须管理线程更无须考虑数据的加解锁换之而来的是更简短可读的代码剩下的事全都扔给操作系统去完成在操作系统那边GCD 在程序运行时管理着一定数量的线程线程的数量是自动分配的取决于用户计算机的配置和用户程序运行时的负载多核工作站每个程序配到的线程自然就会比单核手机或双核笔记本来得多而且这个线程的数量是会动态变化的当程序非常忙时线程数会相应增多而当程序闲置时系统会自动减少其线程数量然后GCD 会一一从队列中读入需要执行的块然后扔到线程上并发执行相信读者已经看出 GCD 和传统线程-锁机制的区别来了传统的方式按劳分配强调程序自由独立地管理妄图通过"无形的手"把系统资源平均分配走的是资本主义市场经济的道路而 GCD 按需分配真正实现了社会主义计划经济管理模式因此在政治上 GCD 就是一个代表先进生产力的计算机技术(我被自己雷了但事实就是这样)GCD 是一个自底向上的技术它实际上由以下 6 个部分组成编译器层面LLVM 为 C、Objective-C 和 C++ 提供了块语法这个内容等下会介绍运行库方面有一个高效分配管理线程的运行库 libdispatch内核方面主要基于 XNU 内核 Mach 部分提供的 Mach semaphores 和 BSD 部分提供的 kqueue () 机制dispatch/dispatchh 提供了丰富的底层编程接口在 Cocoa 层面NSOperation 被重写因为使用 libdispatch所以先前使用 NSOperation 的程序不需改动就自动享受 Grand Central Dispatch 的最新特性Instruments 和 GDB 提供了非常完整的分析和调试工具GCD 还有一些工程上的优势首先程序的响应速度会更快GCD 让程序员更方便地写多线程程序因此写一个多线程程序来实现前后台简单多了极大改善了 Mac OS X 上应用程序的生态环境而且 GCD 的代码块队列开销很小比传统线程轻量得多统计表明传统的 Mac OS X 上使用的 POSIX 线程需要数百个计算机汇编指令占用 512KB 的内存而一个代码块队列才用 256 字节的长度把块加入队列只需要 15 个计算机汇编指令因此开成百上千个也不费什么事其次线程模式是一种静态的模式一旦程序被执行其运行模式就被固定下来了但用户的计算机配置各不相同运行时别的程序有可能耗用大量的计算资源这些都会影响该程序的运行效率而动态分配系统资源则能很好地解决这个问题苹果自然也是不遗余力地忽悠开发者使用 GCD因为各个软件共享多核运算的资源如果 GCD 被更多的开发者采用整个苹果平台的生态也就更健康而最重要的还是 GCD 采用的线程池模式极大简化了多线程编程也降低了出错的可能性著名 FreeBSD 开发者 Robert Watson 还发布了一个他修改过的 Apache并释出了补丁声称只需原先 1/3 至 1/2 的代码量就实现了原先的多线程模块并比原先的效率更好如何应用 GCD当然老王卖瓜自卖自夸没有实际的例子是不能让读者信服的下面我们就来简单讲解 GCD 的技术第一是块状语法是一个对 C、C++ 和 Objective-C 语言的扩展用来描述一个任务用^引导的大括号括起来比如最简单的:x = ^{ printf ("hello world\n");}则 x 就变成了一个块如果执行:x ();那么程序会打印 hello world 出来当然blcok 像函数一样可以跟参数比如:int spec = 4;int (^MyBlock)(int) = ^(int aNum){return aNum * spec;}; spec = 0;printf ("Block value is%d"MyBlock (4));这里 MyBlock 是一个带参数的代码块读者看到这里不禁要问块到底有什么好处它和 C 的函数指针有什么不同我们依然用上面的例子来说明问题虽然后面我们把 spec 变量改为 0但事实上在 MyBlock 创立时已经生成了一个闭包因此它最后输出的结果仍是 16不受 spec 值改动的影响这对于搞函数式编程的人来说再熟悉不过了因此很多开发者亲切地称呼块语法的 C 扩展为"带 lambda 的C"有了闭包功能的 C 顿时牛起来你可以把函数和数据包装在一起这就是块的真正功能因为只要一个闭包包含了代码和数据它的数据就不会被别的闭包轻易改动所以在它执行时你根本不用为数据上锁解锁有了一系列的代码块后接下来的事是把代码块扔到队列里比如最简单的:dispatch_queue_t queue = dispatch_get_global_queue (00);来创建一个轻量级的队列然后dispatch_async (queue^{printf ("hello world\n");});那这个代码块就被扔进 queue 这个队列中了你可以手动依次添加任意多个项目比如"带着老婆"、"出了城"、"吃着火锅"、"唱着歌"、"突然就被麻匪劫了"等当然在更多的场合你会更倾向于使用自动事件源每当一个事件触发时(比如定时器到点、网络传来包裹或者用户点击了按钮)相应的代码块被自动添加到队列中一旦队列不是空的GCD 就开始分配任务到线程中拿上面的例子来说"老婆"、"城"等变量可是封在闭包里的所以在运行时不用考虑它们被某个别的闭包改掉(当然也有方法来实现这个功能)总体而言这个模式比线程-锁模型简单太多它的执行是并行的但思维却是传统的异步思维对没有学习过系统多线程编程的开发者来说依然能很容易地把握读者可能要问如果闭包之间有复杂的依赖关系需要申明某两个操作必须同步或异步怎么办比如"出了城"必须在"吃着火锅"之前在 GCD 中可以使用 dispatch_async 和 dispatch_sync 来描述这样的依赖关系而在 Cocoa 层面NSOperation 中的队列依赖关系甚至可以被描述成有向图GCD 得到广泛应用GCD 一经推出就得到了广泛的应用苹果自家的软件 Final Cut Pro X、Mail 等软件都采用 GCD 来实现任务并发和调度因此 Mac OS X 106 成为了有史以来最快的发行版从 iOS 4 开始iPhone 和 iPad 也加入了 GCD 的支持更别提原先使用 Cocoa 的 NSOperation 相关接口的程序无需改动即享受 GCD 的优待GCD 在 Mac OS X 106 发布后又以 libdispatch 为名作为一个独立的开源项目发布 所需的外围代码如编译器的块支持、运行库的块支持、内核的支持也都能在 LLVM 和 XNU 等开源项目代码中找到所以很快被别的操作系统采用作为 Mac OS X 的近亲 FreeBSD 在一个月后即完整移植了整套 GCD 技术并最终在 FreeBSD 90 和 81 中出现诸多 Linux 发行版也提供 libdispatch 的包使用 Linux 内核的 epoll 来模拟 FreeBSD 的 kqueue2011年 5 月 5 日 Windows 的移植工作也宣告完成另外GCD 也成为挽救动态语言的重要法宝由于受 GIL(全局解释锁)的限制动态语言虽然有操作系统原生线程但不能在多核处理器上并行执行而 GCD 成功绕开了这个限制如加入 GCD 支持的 Ruby 实现 MacRuby 就能在多核处理器上高效执行 因此在苹果生态圈以外GCD 也会得到越来越多的应用半导体的丰收(下)随着 CPU 与 GPU 合并成技术发展的趋势苹果开发出了 OpenCL 框架能够进行高速并行处理的能力使 OpenCL 成为了业界标准被广泛应用最近几年GPU 的发展吸引了很多来自科学计算界人士的目光GPU 有稳定的市场推动力公众喜闻乐见的电子游戏产生了源源不断的升级 GPU 的需求因此比 CPU 的更新步伐更快从技术上讲GPU 本身就是多核架构高端显卡往往有五百多个核心即使低端的集成 GPU 也有二三十个核心所以能够通过并行来高效处理成千上万的线程同时对于科学技算中的浮点计算GPU 往往通过硬件加速使其效率比传统 CPU 更高因为图形渲染等工作基本都是浮点计算GPGPU 浮出水面早期的 GPU 只能执行固定的程序而不开放给程序员编程随着时代的发展图像处理有时需要对着色器进行编程以实现一些特效因此需要程序员可以使用 GPU 的汇编语言写简单的着色程序这自然对程序员要求过高所以一些高阶的着色语言又被 GPU 厂商开发出来比如微软和 NVIDIA 共同开发的 Cg 语言就能为顶点和像素编写专门的着色程序这类技术虽然面向图形渲染工作者却吸引了一小簇科学计算研究者的兴趣以计算流体力学为例它是用纳维斯托克斯方程【注:把牛顿第二定律和质量守恒应用到流体后所得到的偏微分方程】来求解流体力学问题的一种算法广泛用于天气预报、F1 方程式赛车设计等工程领域同时对于电影制片特效计算流体力学也是最基本的用来模拟流体流动特放的算法皮克斯动画工作室的《寻找尼莫》中的海洋流动和水花等都是使用纳维斯托克斯方程来模拟的首先对于一个几何空间进行网格化每个网格中的流体都可以列出纳维斯托克斯方程把这些方程联立起来进行求解即可得到各点的温度、压力、湿度、速度等流体信息整个求解过程可以高度并行因为每个网格的控制方程是完全一样的;同时也牵涉大量的浮点运算但 Cg 这类语言并非面向普通的计算其变量都是颜色、顶点、像素等图形学专用变量来自北卡罗莱那大学教堂山分校的 Mark Harris 突发奇想:可以把流体力学中每个网格的速度、压力等变量存成 RGBA 颜色后让 Cg 去处理所以他在《GPU Gems》中著名的一章公布了使用 Cg 来高速实现计算流体力学运算的成果吸引了大量计算界的目光然而这种编程模式对科技工作者来说很不友好因为这要求一个学力学的、学生物的、学化学的学生先要明白复杂的 GPU 渲染原理了解图形学中材质、顶点、合成、像素、光栅化、光线跟踪等深奥的理论才能编写他们专业相关的 GPU 程序GPU 生产厂商洞悉到了 GPU 高速并行浮点数运算的潜力所以 GPGPU(General Purposed Graphics Processing Unit)概念终于浮出水面一方面 GPU 设计一代比一代可编程化另一方面各公司也在加紧研制新一代 GPU 编程语言新一代的语言对比 Cg去掉了对于渲染相关的知识要求独立于图形学之外是纯粹的普通语言比如变量不再是像素、顶点、面等类型而是 C/C++ 语言开发者喜闻乐见的浮点数组、整形数组等这一时期为代表的语言主要是 CUDA(Compute Unified Device Architecture)CUDA 是 NVIDIA 在 2007 年公布的一项面对科学计算工作者的编程框架通过该技术使用者可利用 NVIDIA 的 GeForce 8 以后的 GPU 和较新的 Quadro GPU 进行高性能编程用户先编写一个特别的 C++ 代码文件扩展名为 cu文件中需要申明创建的变量、GPU 计算核心(kernel)以及使用给定的编程接口来实现变量在 CPU 和 GPU 中的传送然后通过 NVIDIA 自家的编译器编译这个代码链接到 NVIDIA 自家的库上即可把该运算核心编译为 GPU 汇编语句扔到特定型号的 GPU 上高度执行其他厂家也紧随其后比如 AMD 为 ATI 生产的 GPU 卡提供了一个类似的框架叫 Stream SDK(先前被命名为 CTM Close to Metal ATI Stream Computing Technical Overview 03/20/2009 http://enwikipediaorg/wiki/Close_to_Metal)而微软更是趁 Vista 和 Win7 推出了 DirectCompute作为旗下 DirectX 技术的一部分CUDA 并不完美对科学工作者来说CUDA 比 Cg 友好太多使用 CUDA 加速流体力学运算相关的论文更是雨后春笋般涌现然而不久后我发现它存在许多问题首先对初学者来说CUDA 编程模式很容易学混因为一个 GPU 数组和一个 CPU 数组在 CUDA 中的表述都是同样的C指针但对于 GPU 数组和 CPU 数组CUDA 的处理模式完全不同CPU 数组使用常规的 malloc 来初始化而 GPU 数组得使用 CUDA 提供的 malloc所以程序写着写着就忘了一个变量到底是给 CPU 用的还是给 GPU 用的这无疑增加了学习难度同时CUDA 对 C/C++ 语言进行了一系列扩展这不但意味着写的程序不再具有 C/C++ 那样良好的可移植性而且这种计算核心和传统 C 程序混写的编程语言很不美观其次CUDA 这类语言的实现各自为政如果你写了一个 CUDA 程序就意味着这个代码只能运行在 NVIDIA 的显卡上如果想使用 ATI 的显卡呢没门请用 ATI Stream SDK 重写再次CUDA 是在编译时就静态产生 GPU 代码的所以只能产生特定的 GPU 代码如果你发布了一个 CUDA 程序它仅对某几种 NVIDIA 显卡进行特定的代码优化如果 NVIDIA 自家出了一种新显卡很抱歉哪怕新显卡可能兼容老显卡的汇编指令而你的程序恰巧可以在新显卡上跑起来你也无法发挥新显卡的所有特性必须用针对新显卡的编译器重新编译源代码才能够保证程序在新显卡上高效执行最后CUDA 这类语言仅能产生高效的 GPU 代码而无法产生 CPU 代码即:写完的代码只能跑在 GPU 上在 CPU 上只能"模拟执行"仅供调试用所以在一台不具备给定 GPU 的机器上无法高效运行 CUDA 程序同样如果你有一个性能很强的工作站那么你的 CPU 亳无用处CUDA 不可能分配一部分任务给 CPU 完成另外还有未来计算机架构的不确定性当时GPU 越来越一般化可以跑多种数值计算程序而 CPU 随着多核成为主流也越来越像 GPU所以很多厂家在考虑 CPU 和 GPU 合并的可能性当时轰动一时的热门事件是 CPU 厂商 AMD 买下了 GPU 厂商 ATI来开发下一代处理器 AMD Fusion把 GPU 和 CPU 合并到一起Intel 自然不甘示弱做出了 Nehalem 平台在该平台上CPU 和集成 GPU 处于同一个包装中外界一度猜测这样可使合并后的 CPU 具有图形处理工能从而用户购置计算机就不用再考虑配一块 GPU 了更强大的是当时 Intel 还公布了 Larrabee 计划让 GPU 支援 x86 指令使得一个常规的 x86 平台的程序不需要修改和重新编译便可在 GPU 上运行虽然事实和这些预期有稍许出入但当时的技术趋势是:在将来可能出现一种新的合并 GPU/CPU 的技术能够并行高速地运行一般的计算机程序而面对这样新的可能的平台我们如何准备OpenCL 诞生OpenCL 则是苹果为这个新局面画下的蓝图这项技术初期全称为 Open Computing Library(如果留意苹果早期宣传广告的话)后改名为 Open Computing Language这项技术从本质上来说和 CUDA 并没有太多的两样但由于苹果在借鉴他人技术并把他人技术改得更棒这一点上是出了名的所以 OpenCL 很好地解决了以上所有问题下面简单介绍一下这个框架OpenCL 技术的结构十分清楚对程序员来说它是一个 Mac OS X 的 Framework定义了两套标准一套是一个 C 语言的编程界面(API)使得开发者创建、拷贝、回收 GPU 使用的对象同时也包含检测处理器、为该处理器编译并调用核心程序(kernel)相关的接口;另一套是 OpenCL 核心程序语言的定义是一套基于 C99 发展而来的语言例如我们有两个大数组1024 维的 a 和 1024 维的 b(当然1024不算大OpenCL 往往用来处理十万、百万数量级的任务)我们把两个数组对应的元素加和结果是一个 1024 维的数组cC 程序员很容易能写出下面的程序:for (int i = 0; i < 1024; i++)c[i]=a[i]+b[i];OpenCL 的核心程序则是取每个独立的可并行的循环分支即上面程序中的 c[i]=a[i]+b[i]所以核心程序大概是下面这样:__kernel add (float *a float *b float *c){int i = get_global_id (0);c[i]=a[i]+b[i];}其中get_global_id () 函数可以返回当前函数是全局中的第几个元素把该程序保存为 addcl就是一个 OpenCL 的核心程序为 C99 语言的一个子集使用 OpenCL 的 API 就能调用这个核心程序每个 OpenCL 程序基本上是模式化地照搬下面流程:1 探测硬件(用 clGetDeviceIDs 函数护取计算设备(可以指定使用 GPU 或是 CPU)用 clCreateContext 函数来新建一个上下文(context)用 clCreateCommandQueue 函数针对设备和上下文新建一个命令队列);2 编译核心(读入 addcl用 clCreateProgram-WithSource 和 clBuildProgram 以及 clCreateKernel 来编译读进来的字符串产生一个核心程序);3 写入数组(用 clCreateBuffer 创建a、b、c三个内存对象用 clEnqueueWriteBuffer 把 C 数组写到内存对象中);4 运行核心(把内存对象作为核心程序函数的输入参数执行这个核心程序会并发为 1024 个线程每个线程执行一次相应的加法运算);5 读出结果(用 clEnqueueReadBuffer 读取c内存对向写为C的数组);6 回收内存OpenCL 之美让我们逐条来看前面那些问题是如何被解决的首先OpenCL Framework 由 C API 和 OpenCL 语言组成泾渭分明所有的 GPU 变量在 C API 中都是内存对象的形式出现有别于 C 自建的数组因此你永远不会搞混两者同理OpenCL 核心程序是独立在 C 源程序之外的不仅美观也能保证你的 C 程序能被所有 C 编译器编译因为调用 OpenCL 库和调用其他 C 的函数库没有任何不同其次苹果开发出 OpenCL 后觉得该技术甚好索性联合 AMD、ARM、ATI、TI、Intel、IBM、Nokia 等公司把它做成一个由 Khronos 组织主持的开放标准不管电脑上用的显卡是 ATI 的还是 NVIDIA 的OpenCL 都能像 OpenGL 那样在你的设备上无缝运行事实上OpenCL 已同 OpenAL 和 OpenGL 一样成为 Khronos Group 旗下的三大业界标准再次CUDA 是在编译时就静态产生 GPU 代码的所以只能产生特定的 GPU 代码而 OpenCL 的核心程序(kernel)是在运行时被编译成 GPU 指令的由于 kernel 所用的 OpenCL 语言仅是 C99 的一个子集所以负责编译这个程序的是 OpenCL 运行库自带的 LLVM-Clang这样做的好处是明显的举例来说如果用户有一堆 OpenCL 的程序比如苹果最新的 Final Cut Pro X 就在许多地方采用了 OpenCL如果某一天硬件厂商发布了一个全新的 GPU 架构那么用户安装显卡后只要下载或更新相关的驱动程序和运行库即可而不需要再求软件厂商发布一个新版本的 Final Cut Pro X因为 OpenCL 在运行时会根据显卡厂商提供的驱动和新运行库自动优化程序到特定架构上所以程序兼容性问题也被圆满解决最后由于 OpenCL 是个开放标准也支持 CPU 和其他任何计算设备比如数字信号处理芯片(DSPs)和各种专门的处理器架构所以只要有相关的驱动和运行库OpenCL 程序可以高效地并行运行在任何架构的运算设备上由于 OpenCL 和 GCD 的编程模式是一样的因此当 OpenCL 程序在 CPU 上执行时是跑在 GCD 队列上的由于 OpenCL 能高速地进行并行处理(如 http://macresearchorg/opencl_episode1 的演示OpenCL 编写的 GPU 程序比单核 CPU 能快上数十至数百倍笔者的论文 Yue Wang Ali Malkawi Yun Yi Implementing CFD (Computational Fluid Dynamics) in OpenCL for Building Simulation 12th Conference of International Building Performance Simulation Association 2011 也得出了类似的结论)OpenCL 被广泛地使用在很多产品中苹果也是 OpenCL 的主要用户之一如上面提到的 Final Cut Pro X 就是个典范使用 GCD 和 OpenCL 进行大量并行的流媒体处理在老版本 Final Cut 中每当用户执行一次流媒体操作都会弹出一个进度条来告诉用户剩余的处理时间而 Final Cut Pro X 优化后的速度是如此实时以至于这个进度条被去除了Mac OS X 许多的底层库也使用 OpenCL 重写如 Core Image本身也是一个 GPU 加速库使用 OpenCL 后相比原来依然获得了可观的性能提升Snow Leopard 的发布标志着第一个 OpenCL 框架的完整实现OpenCL 成为业界标准后AMD 抛弃了原先的策略投入开放标准的怀抱一连放出了几个测试版本的集成 OpenCL 的 ATI Stream SDK并在 2009 年年底发布了稳定版2011年 8 月 8 日宣布废除原先的 Close to Metal 相关技术NVIDIA 也是早早地在 CUDA SDK 中加入了 OpenCL 相关的库CUDA 越来越不被看好所以 NVIDIA 干脆把 CUDA 发布为一个开源项目并把 CUDA架构在 LLVM 之上这和 OpenCL 近几年的走强有很大关系开发者的瓶颈目前看来OpenCL 虽然解决了上面的所有问题且速度飞快但对普通程序员来说依然是非常底层的技术而且由于硬件的限制(显卡不支持指针运算)很多 C 的标准并未在 OpenCL 中出现写链表还需要用整数去模拟地址程序员需要手动管理内存处理底层的核心调用以及数据读写而显卡厂商也大多不愿公开 GPU 的技术细节因此不像 CPU 程序很容易通过汇编指令分析计算机底层干了什么显卡对于开发者纯粹是个黑盒把整个问题分成多少个线程并发也没有一个规律可循有可能不起眼的改动会使程序运行瞬时变快或变慢数十倍开发者也不知道其中的原因只能凭经验操作而且由于不存在良好的调试工具所以很难改正程序的错误显卡作为系统最为重要的共享资源之一不像现代操作系统那样提供内存保护机制因此一个用户 OpenCL 程序的错误很容易导致整个计算机崩溃所以经常是程序跑一遍后发现操作系统挂了重启后发现了一个可能的错误改完后编译运行操作系统又挂了我用 OpenCL 编写科学计算程序时大量时间是在重启电脑而不是写程序这些问题仍旧阻碍着 OpenCL 被广泛采纳不过在科学计算界已经涌现出了越来越多相关的论文和技术相信在不久的将来情况会有所改观结语当写完这篇技术长文时天色已晚走出教室和 ENIAC 擦肩而过ENIAC 的出现鼓励了之后一次次的处理器革命2009 年发布的 Snow Leopard 可能在整个 Mac OS X 发行版历史中不算最出彩却是对于半导体集成电路革命的一次重大收成Mac OS X背后的故事(十)Mac OS X 文件系统的来龙去脉(上)HFS+ 和 UFS 文件系统同时被引入早期的 Mac OS X随着若干年的发展HFS+ 提供的功能已超越 UFS使其在 Mac OS X 105 之后成为成为唯一正式的 Mac OS X 系统但因为其背负许多的历史包袱为考虑兼容性这些陈旧的设计并不能被推翻重来所以苹果开始秘密研发下一代的文件系统著名 BSD 开发者 Marshall Kirk McKusickUFS:经典的 Unix 文件系统在 Unix 系统刚诞生的远古时期文件系统被简单地称为 FSFS 只包括启动块、超级块(处于硬盘分区开头用来保存文件系统信息)、inodes(索引节点)及数据FS 文件系统在 Unix 系统刚诞生时还能满足新老客户的需求但随着科学技术的进步FS 已不能符合现代文件系统的需求且会导致抖动等一系列问题当时还是加州大学伯克利分校研究生后成为著名 BSD 开发者 Marshall Kirk McKusick 在 BSD 41b 上承接传统的 FS 文件系统实现了 FFS(Fast File System)妥善地解决了这一难题把先前整块的磁盘文件系统分为小块每块包含自已的索引节点和数据因而增加了文件的局部性减少了寻道时间由于 Marshall Kirk McKusick 的 FFS 文件系统很好很强大所以立即被各大 Unix 系统所使用SunOS/Solaris、System V Release 4、HP-UX 及 Tru64 UNIX 都使用它也成为当今各 BSD 分支(FreeBSD、OpenBSD、NetBSD 及 DragonFlyBSD)的标准文件系统每个不同的系统无论开源与否又会在 FFS 文件系统上增加各种扩展这些扩展往往不互相兼容但奇妙的是大家又都使用和原版同样的块大小和数据块宽度因此在很大程度上这些山寨版 FFS 文件系统又相互兼容至少在一个操作系统上能对另一操作系统的文件系统执行只读操作因此FFS 事实上已经成为 Unix 系统的标准文件系统故它有了一个更广泛的称谓UFS(Unix File System即 Unix 文件系统)UFS 在后来的若干年又取得了长足的发展Sun 公司在 Solaris 7 系统中给 UFS 提供了简单的日志功能日志文件系统指在档案系统发生变化时先把相关的信息写入一个被称为日志的区域然后再把变化写入主文件系统的文件系统在文件系统发生故障(如内核崩溃或突然停电)时日志文件系统更容易保持一致性并且可以较快恢复Marshall Kirk McKusick 又实现了 BSD 一度引以为豪的 Soft Update 功能来保证计算机掉电或系统崩溃时通过使元数据按依赖顺序更新来确保磁盘上总的文件系统保持一致的实现机制Soft Update 的目标和日志类似但实现代价比日志轻量许多不过这项功能有所代价主要是需要引入一个后台 FSCK 检查2009 年Jeff Roberson 正式发表了对 UFS 的一项改进为 Soft Update 加入了日志功能并排除了对 FSCK 的依赖这项改进最终集成进了 FreeBSD 9 中TrustedBSD 项目又为 BSD 分支的文件系统设计了 ACL 访问控制表功能(Access Control Lists)先前Unix 文件系统的访问控制是非常简单的其权限管理分为三个不同的类别:用户、同组用户以及其他用户对每个类别Unix 文件系统提供读、写、执行三种权限的治理这样的许可管理过于粗糙无法指定某一用户访问的权限也无法指定更为细致的权限内容(例如准许对一文件实行删除操作)为解决这个问题访问控制表被增加到文件系统中使用以存取控制矩阵为基础的存取控制方法存取控制串列描述每一个文件对象各自的存取控制并记录可对此物件进行存取的所有主体对对象的权限总之UFS 与时俱进不断增加新的功能HFS+:更现代的 HFS作为 Mac OS X 的老祖宗 NeXTSTEP因为基于 BSD所以自然也使用 UFS而老版的 Mac OS 则使用一个叫做 HFS 的文件系统HFS 是一个比较古老且不思进取的文件系统因此在 20 世纪 90 年代末已不能满足当时的需要在《Mac OS X 背后的故事(一)》中我们提到为了实现 Mac OS 的现代化Copland 项目被提出Copland 项目的子项目 Sequoia 旨在 HFS 的基础上加入现代文件系统所必需的新功能如大文件支持、Unicode 文件名支持、长文件名支持、32 位文件映射表支持等Sequoia 项目即成为后来熟知的 HFS+由 Don Brady 领导这个团队先花了 6 个月时间把 HFS 项目原本的 Mac 使用的 68K 处理器汇编码改写成 C 代码然后逐渐加入新功能后来由于 Copland 被力挽狂澜的 Ellen Hancock 给废了所以一些有用的更新如 HFS+ 即被集成到 Mac OS 81 中在 Mac OS X 诞生初期HFS+ 和 UFS 文件系统同时被引入早期的 Mac OS X 中不过由于 HFS+ 根植 Mac OS缺乏 Unix 文件系统所必需的功能如符号链接、硬链接及其他各种 POSIX 兼容性所以 HFS+ 开发组又花了一些工夫在不影响和 Mac OS 兼容性的情况下引入了这些功能由于 HFS+ 是对 HFS 的扩展故 HFS+ 支持 Mac OS 至 Mac OS X 的平滑过渡所以 Mac OS X 一直默认使用 HFS+但当时的 UFS 提供比 HFS+ 更先进的功能因此 Mac OS X 100 至 104也都支持把系统安装在 UFS 系统上Mac OS X 100 发布后苹果不遗余力地对 HFS+ 进行大规模的扩展和维护增加了很多 UFS 独有的功能这些新功能使得文件系统更加安全稳定可靠例如 Mac OS X 1022 中HFS+ 支持日志日志功能在 Mac OS X 102 服务器版中可以简单地设定但在普通桌面版中需要使用命令行进行操作在 Mac OS X 103 中带日志功能的 HFS+(被称为 HFSJ即 HFS+ volume with journal)成为默认设置Mac OS X 103 亦增加文件名、目录名区分大小写及 Unicode 32 的支持Mac OS X 104 中HFS+ 更是增加了 ACL 访问控制表功能提供更复杂的对传统 Unix 文件系统权限的扩展文件系统除了让用户供稳定地存放文件这一目标以外还是各项操作系统功能的基础Mac OS X 每个大发行版都要增加数百项新功能许多新功能严重依赖于文件系统的实现Mac OS X 103 提供了 FileVault 来加密用户文件因此用户主目录被保存在一个 HFS+ 文件系统加密镜像中Mac OS X 104 提供了系统内置的 Spotlight 桌面搜寻搜索功能能让用户对整个磁盘系统进行快速搜寻、随打即显这项功能要求文件系统提供任意长度文件元数据(metadata)的支持Mac OS X 104 转向了对 Intel 处理器的支持因此苹果发布了一个测试版本的 BootCamp 来让用户安装 Mac OS X、Windows 双系统并在 Mac OS X 105 正式集成进系统哪怕在 Mac OS X 系统运行BootCamp 也可以实时调整系统主分区的大小来空出磁盘空间给 Windows因此HFS+ 又需要支持动态分区大小调整在 Mac OS X 105 中集成了 Time Machine它是苹果公司所推出备份的工具程序于 2006 年 8 月 7 日在苹果计算机全球研发者大会(WWDC)中首次公开成为当天观众欢呼声最高的功能Time Machine 对于修改过的文件会在备份盘上保存一个新拷贝而对于不变的内容仅在备份盘上存一个指向先前文件的硬链接因此每一次快照只保存改动的文件而别的文件只保存占用空间很少的硬链接但 Unix 一般只支持文件的硬链接而不支持目录的硬链接因此 HFS+ 在这点上走得比 Unix 文件系统更远提供了对于目录的硬链接支持在 Mac OS X 106 中HFS+ 甚至支持文件系统压缩使得安装后占用比 Mac OS X 105 少得多的空间Mac OS X 107 提出了 FileVault2能加密整个磁盘而不是一个用户目录这些功能我们在为读者介绍每个发行版时亦会提到但总之读者看到HFS+ 的功能随着 Mac OS X 的商业需求不断被扩展"我在做了这么多工作后回想才发现我们为 HFS+ 增加了那么多新功能"苹果前文件系统开发者 Don Brady 如是说由于 HFS+ 经过后来若干年的发展提供的功能已不逊于 UFS甚至更多更好故至 Mac OS X 105 砍掉了安装至 UFS 的支持HFS+ 成为唯一正式的 Mac OS X 系统HFS+ 并不完美HFS+ 自发布以来几乎每个发行版都有令人欣喜的改动它也逐渐成为一个非常完善的文件系统但 HFS+ 立足于 HFS 设计HFS 已有 27 年的历史HFS+ 亦有 14 年历史这个文件系统有太多的历史包袱为考虑兼容性这些陈旧的设计并不能被推翻重来HFS+ 基于B-树实现当查找B-树中未使用的节点时HFS+ 只能每次处理 16 位原因是老 Mac 使用的 Motorola 的 68K 芯片原生支持 16 位的数据操作但不管是 PowerPC 还是 Intel寄存器都支持 256 位宽的寄存器HFS+ 的元数据(metadata)都以大字节序保存原因是 Motorola 的 68k 和后来 Mac 使用的 PowerPC 都使用大字节序但经过 Intel 迁移后当今的 Mac 都使用 Intel 芯片而 Intel 芯片是使用小字节序的因此每当数据读取或存入时还要经过小字节序和大字节序的转换远古时期磁盘很慢计算机处理器的速度也很低因此进行一次磁盘操作会占用较多的时间HFS+ 的时间辨别率为一秒但当今的磁盘、处理器处理一次文件系统操作的时间远小于一秒因此所有主流磁盘文件系统的时间辨别率都是一至数百纳秒级别的HFS+ 的元数据有全局锁同一时间只有一个进程可以访问更新文件系统在单核处理器连手机平板都较少见到的当今这种设计显得很稚嫩HFS+ 亦没有稀疏文件的支持例如我们在 SQL 中建立了一个数据库SQL 分配了 10GB 的文件给这个数据库并且在文件头和文件尾写上一些字节的数据而由于我们还没有给这个数据库添加新的数据所以这 10GB 的文件除了头尾外其他字节都为0现代的文件系统基本都支持稀疏文件也就是说当处理这个数据库操作时事实上往磁盘写入的数据只有那文件头和文件尾的若干字节而 HFS+ 则需要把那些 0 也写上因此会完整写入 10GB 的数据耗费长得多的时间此外HFS+ 不具备元数据校验功能、快照功能、写入时复制功能、就地执行功能、逻辑卷管理功能等很多现代磁盘系统所具备的功能也不能动态调整文件块大小这些功能的加入并不容易其中最要命的是HFS+ 不像一些先进的文件系统支持写入时复制事务模型也没有快照和克隆这使得用户数据时时处于风险之中例如由于因为断电、内核崩溃等原因文件系统上写到一半的数据小则导致个别文件损坏大则导致整个文件系统崩溃在生产领域这样不可靠的文件系统很有可能带来致命的灾难正是由于上述这些原因连我们介绍过的短视的 Linus Torvalds 都认为 HFS+ 是个垃圾文件系统苹果自然受不了这种侮辱因此干掉 HFS+ 势在必行用什么取代 HFS+ 呢苹果开始秘密研发下一代的文件系统(下)由于各种缺点干掉 HFS+ 势在必行然而用什么取代 HFS+ 呢苹果开始秘密研发下一代的文件系统ZFS然而在诸多因素的干扰下MacOSX 的 ZFS 支持却只是昙花一现未来文件系统之路将走向何方文件系统的新时代ZFS为了代替 HFS+苹果开始为研发下一代文件系统招兵买马准备大干一场但这时 Sun 公司的工作让苹果的员工们为之一振2004 年Sun 公司发表了其杰出的文件系统ZFS这是一个 128 位的文件系统本为 Solaris 操作系统开发于 2005 年 10 月 31 日并入了 Solaris开发的主干原始码后成为一个使用 CDDL 协议条款授权的开源项目ZFS 是一个具有高存储容量、文件系统与卷管理概念整合、崭新的磁碟逻辑结构的轻量级文件系统同时也是一个便利的存储池管理系统ZFS 的一个重大特点就是拥有大容量ZFS 是一个 128 位的文件系统这意味着它能存储 1800 亿亿(1841018)倍于当前 64 位文件系统的数据ZFS 的设计如此超前以至于这个极限就当前现实而言可能永远无法遇到项目领导 Bonwick 曾说:"要填满一个 128 位的文件系统将耗尽地球上所有存储设备除非你拥有煮沸整个海洋的能量"假设每秒钟创建 1000 个新文件达到 ZFS 文件数的极限需要约 9000 年此外ZFS 的一个重要指导思想是不单单去做一个文件系统而是实现一套完整的卷管理方案不同于传统文件系统需要驻留于单独设备或者需要一个卷管理系统去使用一个以上的设备ZFS 建立在虚拟的被称为"zpools"的储备池之上每个存储池由若干虚拟设备组成这些虚拟设备可以是原始磁碟也可能是一 RAID1 镜像设备或是非标准 RAID 等级的多磁碟组于是 zpool 上的文件系统可以使用这些虚拟设备的总存储容量有了卷管理方案后ZFS 走得更远加入了快照和克隆等实用的文件系统功能当 ZFS 写新数据时包含旧数据的块被保留磁盘只写入修改过的那部分数据块所以快照的建立非常快只存储两个快照间的数据差异因此快照也是空间优化的克隆指两个独立的文件系统共享一些列的块当任何一个克隆版本的文件系统被改变时只创建改动的数据块因此非常快速也占用少得多的空间而 ZFS 最大的奉献在于它是第一个支持写入时复制功能(COWcopyonwrite)的文件系统所有文件系统中的块都包括 256 位的校验值含有活动数据的块从来不被覆盖;而是分配一个新块并把修改过的数据写在新块上所有与该块相关的元数据块都被重新读、分配和重写因此当一个数据写入时发生了任何意外错误原先的数据依然可以被访问且文件系统知道哪个操作出了错误而没有完成ZFS 的快照和克隆正是因此项技术而得以实现ZFS 对于用户而言界面友好先前 Unix的卷管理非常烦琐FreeBSD 因此还建了一套雄伟的框架给逻辑卷管理做深层次的抽象而 ZFS 文件系统自带卷管理方案几乎所有烦琐复杂的操作都能在一两条命令内完成我用传统的卷管理工具已有近十个年头第一次使用 ZFS 时完全被其易用性震动所以我毫不犹豫地把手头所有的服务器迁移到了 ZFS由于 ZFS 各种美好加上其开源性质所有的操作系统都想支持它Solaris、OpenSolaris 项目一直作为标准实现供其他系统参考PaweJakubDawidek 把 ZFS 移到 FreeBSD并在2009 年进入了 FreeBSD7作为 FreeBSD 第七版最耀眼的三项功能之一(另一项功能是我们先前提到的 ULE以及 SunDTrace 的移植工作)NetBSD 在 2009 年正式收纳 ZFSLinux 则麻烦得多因为 Linux 内核的协议 GPL 是个和很多协议都水火不容的奇葩协议ZFS 分发所采用的 CDDL 和 GPL 会产生冲突所以一方面 FUSE提供了用户空间层面的支持;另一方面由 Oracle 牵头专为 Linux 开发 Btrfs事实上就是一个 ZFS 的山寨版惋惜折腾了几年Oracle 自己又把 Sun 收购了且到我撰写此文时 Btrfs 依然没有正式的稳定版本发布昙花一现的 ZFS 梦刚才提到苹果在招兵买马雇员工开发新一代的文件系统而 ChrisEmura(AppleCoreOS的文件系统开发经理)及 DonBrady(先前提到此人领导 HFS+ 的开发)两个富有体会的文件系统开发者却被衣服一样晾在了一边无所事事2006 年刚刚提到的 PaweJakubDawidek 正在往 FreeBSD 迁移 Sun 的 ZFS这项工作立刻引起了 ChrisEmura 及 DonBrady 的高度兴趣由于 ZFS 在 Unix 系统高度的可移植性加上 MacOSX 本就是 FreeBSD 的近亲闲得发慌的两人立刻打算往 MacOSX 移植 ZFS在 2007 年 4 月 6 日FreeBSD 的移植宣告完成等待合并进主干一周后两位苹果员工亦成功地完成了 MacOSX 的移植苹果一看两人的 ZFS 的移植工作大有前途立即跟进2007 年的苹果全球开发者大会上苹果让 ChrisEmura 及 DonBrady 举办了一场小型讲话介绍 MacOSX 对 ZFS 的支持这场讲话先前并没有在官方声明中告示但讲话的报告厅依然挤满了听众随后 ZFS 移植的源码在 MacOSForge 公布在最终版的 MacOSX105 带有试验性的 ZFS 只读支持以命令行方式提供用户可以挂载 ZFS 的存储池并对池中的文件系统进行读取操作苹果一直使移植并使用 Sun 的关键技术除了 Java 以外MacOSX105 的 Xcode 套件也加入了 DTrace 的支持并提供了一个好用的图形界面 Instruments 让开发者更方便地调用 DTraceZFS 除了解决 HFS+ 的所有问题提供安全可靠的文件系统基础外还可以简化苹果许多软件的实现例如前文提到的 MacOSX105 的 TimeMachine实现颇为烦琐依赖于给 HFS+ 提供新功能功能层也需要增加很多的和备份相关的代码而 ZFS 默认就支持快照将大大简化 TimeMachine 的实现并使该功能更稳定可靠事实上在 2008 年 11 月 25 日Sun 发布了 OpenSolaris200811 版其中给 GNOME 的 Nautilus 增加了一个使用 ZFS 的快照功能的图形界面插件名为 TimeSlider和苹果的 TimeMachine 提供了非常相近的功能我在使用后感觉不错因此在 WWDC2008 上SnowLeopard 被提出其中一项很重要的卖点就是对 ZFS 的完整的读写支持在 MacOSX 的服务器版苹果也将提供一套图形界面工具来方便维护人员管理 ZFS 存储池在当时的 SnowLeopardServer 主页上苹果声明 ZFS 将作为一项主推功能但好景不长一年后的苹果开发者大会时ZFS 相关的内容被悄悄从任何公开的文档、网站、发布会中撤下没有给出任何的理由MacOSForge 上的 ZFS 代码和页面也被苹果移除外界有很多对此的猜测但没有任何猜测得到苹果官方的或是哪怕离职员工的证实猜测之一是当时 Sun 刚被 Oracle 收购而 Oracle 长期投资 ZFS 的竞争产品 Btrfs因此苹果觉得 ZFS 的前途不甚明朗猜测之二是 ZFS 的关键技术 CopyOnWrite 有专利问题NetApp 声称他们拥有 COW 的专利因此在起诉 Sun苹果不想在当中冒风险猜测之三是 ZFS 和苹果的 XNU 内核有协议冲突我虽然不学法律但我认为这个说法不完全对因为 ZFS 和 DTrace 一样是以 CDDL 发布的开源软件既然 DTrace 可以无后顾之忧地加入到 XNU 中ZFS 也没有理由不可以事实上除了 Linux 这种少数使用 GPL 这类奇葩协议的内核大多数系统的协议都不和 CDDL 冲突FreeBSD 也好MacOSX105 也罢都把 ZFS 加入内核发布但事实上如果把三种猜测并在一起我们可以看到一个更全局的可能性:对于猜测之二苹果可能并非想使用 CDDL而是想从 Sun 买下一个私有的协议这样一来Sun 不但提供更好的技术支持出了问题(比如猜测二中的专利问题)也可以让 Sun 为自己背黑锅结果 Sun 可能和苹果价格谈不拢加上猜测之一提到的 Sun 大势已去让苹果觉得还不如自己造个轮子来得方便Sun 公司开发 ZFS 的主力 JeffBonwick 虽不能提供详细的信息但他基本证实了这种说法无论如何MacOSX的 ZFS 支持如昙花一现般消逝了未来文件系统之路走向何方虽然 MacOSX的 ZFS 支持被砍了开源社区依然想继续开发 MacOSForge 先前版本的移植如 MacZFS 项目不遗余力地给 MacOSX105~107 提供 ZFS 读写支持DonBrady 在苹果将对 ZFS 的支持砍掉之后从工作了 20 多年的苹果离职开了一家名为 TensComplement 的公司该公司提供 Z-410较 MacZFS 提供更新更稳固的移植不过砍了 ZFS 后的苹果目标也变得更清楚和 Sun 的谈判让苹果觉得与其支付高额的协议费还不如雇人自己做个新的再说了作为比 Sun 大得多的 IT 公司苹果可以轻而易举地搞个更强大的东西灭了它因为 ZFS 其实也不如传说中的那样好首先时代在进步ZFS 之后又有很多新的和文件系统相关的研究如 OhadRodeh 的论文即成为后来 BtrFS 实现的基础可能比 ZFS 做得更好其次ZFS 是十年前开始设计的文件系统但十年中存储工具已发生了重大的变化ZFS 为传统磁盘设计但传统磁盘的市场空间已不断被 SSD、闪存的吞食尤其是 MacBookAir 中使用的 Flash 存储器便宜好用又小巧可能将来会在 MacBookPro 甚至 iMac 中得到更大的推广采用为传统磁盘优化的 ZFS 就不显得那么有吸引力最后ZFS 和苹果有不同的用户群ZFS 目标用户是大企业的工作站和服务器在那里大容量的存储空间、高级的卷管理显得非常重要但苹果面对的基本都是个人用户先前苹果还卖服务器但后来 Xserve 都被苹果砍了有几个个人用户需要使用到 ZFS 这些高级的功能呢更重要的苹果的主要利润将移到 iPhone、iPod、iPad、AppleTV 这些小设备上ZFS 需要占用大量的内存来实现文件系统操作在这些小设备上内存很少ZFS 根本跑不起来苹果非常清楚这些问题工程师们现在一定在紧锣密鼓地开发下一代文件系统在 107 及 108 中这套文件系统并未浮出水面但一些细节值得留意在 107 中苹果发布了 CoreStorage但并未声张这是一套逻辑卷管理工具类似于前文提到的 FreeBSD 的 GEOM这个版本的 FileVault2 亦使用 CoreStorage 重写可以看到虽然苹果在上层不断地淡化文件系统的概念例如 iCloud 的发布和 iOS 中对于文件这一概念的故意忽略但苹果在底层文件系统上的动作越来越大想必在将来苹果定会让我们感到重大的惊喜而对外政策更是一个大手笔。90年代完全按照“华盛顿共识”进行改革。林老师的理论构架。