应用 fork-join 框架---硬件革新对软件的发展

 IBM DeveloperWorks  Java 理论与实践: 应用 fork-join 框架
[

硬件趋势驱动编程语言

语言、库和框架形成了我们编写程序的方式。Alonzo Church 早在 1934 年就曾表明,所有已知的计算性框架对于它们所能表示的程序集都是等价的,程序员实际编写的程序集是由特定语言形成的,而编程模型(由语言、库和框架驱动)可以简化这些语言的表达。

另一方面,一个时代的主流硬件平台形成了我们创建语言、库和框架的方法。Java 语言从一开始就能够支持线程和并发性;该语言包括像 synchronizedvolatile 这样的同步原语,而类库包含像 Thread 这样的类。然而,1995 年流行的并发原语反映了当时的硬件现状:大多数商用系统根本没有提供并行性,甚至最昂贵的系统也只提供了有限的并行性。当时,线程主要用来表示异步,而不是并发,而这些机制已足够满足当时的需求了。

随着多处理器系统价格降低,更多的应用程序需要使用这些系统提供的硬件并行性。而且程序员们发现,使用 Java 语言提供的低级原语和类库编写并发程序非常困难且容易出错。在 Java 5 中,java.util.concurrent 包被添加到 Java 平台,它提供了一组可用于构建并发应用程序的组件:并发集合、队列、信号量、锁存器(latch)、线程池等等。这些机制非常适合用于粗任务粒度的程序; 应用程序只需对工作进行划分,使并发任务的数量不会持续少于可用的处理器数量。通过将对单个请求的处理用作 Web 服务器、邮件服务器或数据库服务器的工作单元,应用程序通常能满足这种需求,因此这些机制能够确保充分利用并行硬件。

技 术继续发展,硬件的趋势非常清晰;Moore 定律表明不会出现更高的时钟频率,但是每个芯片上会集成更多的内核。很容易想象让十几个处理器繁忙地处理一个粗粒度的任务范围,比如一个用户请求,但是这 项技术不会扩大到数千个处理器 — 在很短一段时间内流量可能会呈指数级增长,但最终硬件趋势将会占上风。当跨入多内核时代时,我们需要找到更细粒度的并行性,否则将面临处理器处于空闲的风 险,即使还有许多工作需要处理。如果希望跟上技术发展的脚步,软件平台也必须配合主流硬件平台的转变。最终,Java 7 将会包含一种框架,用于表示某种更细粒度并行算法的类:fork-join 框架

实现更细粒度的并行性

如 今,大多数服务器应用程序将用户请求-响应处理作为一个工作单元。服务器应用程序通常会运行比可用的处理器数量多很多的并发线程或请求。这是因为在大多数 服务器应用程序中,对请求的处理包含大量 I/O,这些 I/O 不会占用太多的处理器(所有网络服务器应用程序都会处理许多的套接字 I/O,因为请求是通过套接字接收的;也会处理大量磁盘(或数据库)I/O)。如果每个任务的 90% 的时间用来等待 I/O 完成,您将需要 10 倍于处理器数量的并发任务,才能充分利用所有的处理器。随着处理器数量增加,可能没有足够的并发请求保持所有处理器处于繁忙状态。但是,仍有可能使用并行 性来改进另一种性能度量:用户等待获取响应的时间。

一个典型网络服务器应用程序的例子是,考虑一个数据库服务 器。当一个请求到达数据库服务器时,需要经过一连串的处理步骤。首先,解析和验证 SQL 语句。然后必须选择一个查询计划;对于复杂查询,数据库服务器将会评估许多不同的候选计划,以最小化预期的 I/O 操作数量。搜索查询计划是一种 CPU 密集型任务;在某种情况下,考虑过多的候选计划将会产生负面影响,但是如果候选计划太少,所需的 I/O 操作肯定比实际数量要多。从磁盘检索到数据之后,也许需要对结果数据集进行更多的处理;查询可能包含聚合操作,比如 SUM、AVERAGE,或者需要对数据集进行排序。然后必须对结果进行编码并返回到请求程序。

就像大多数服务器请求一样,处理 SQL 查询涉及到计算和 I/O。虽然添加额外的 CUP 不会减少完成 I/O 的时间(但是可以使用额外的 内存, 通过缓存以前的 I/O 操作结果来减少 I/O 数量),但是可以通过并行化来缩短请求处理的 CPU 密集型部分(比如计划评估和排序)的处理时间。在评估候选的查询计划时,可以并行评估不同的计划;在排序数据集时,可以将大数据集分解成更小的数据集,分 别进行排序然后再合并。这样做会使用户觉得性能得到了提升,因为会更快收到结果(即使总体上可能需要更多工作来服务请求)

fork-join 方法提供了一种表示可并行化算法的简单方式,而不用提前了解目标系统将提供多大程度的并行性。所有的排序、搜索和数字算法都可以进行并行分解(以后,像 Arrays.sort() 这样的标准库机制将会使用 fork-join 框架,允许应用程序免费享有并行分解的益处)。随着处理器数量的增长,我们将需要在程序内部使用更多的并行性,以有效利用这些处理器;对计算密集型操作(比如排序)进行并行分解,使程序能够更容易利用未来的硬件。
]
    以前一直觉得硬件和软件都是独立发展的,硬件的革新也不会导致太大的软件开发方面的不同,多核处理器的出现也不是什么大不了的事情。开发软件都老老实实的设计好数据结构,算法,借口,搞搞设计模式,问题解决了就可以了。可是看了这篇文章才发现那些大佬们的想法果然不同,以后需要多多关心相关的消息了。
    虽然fork-join框架提供了一种简单的接口,但是谁知道以后还会冒出来什么。等到Java7出来以后再研究吧。

你可能感兴趣的:(java,框架,服务器,语言,任务,数据库服务器)