1.2.2 多核编程

怎样才能充分利用这场多核处理器新革命的优势呢?

答案是并发。 没错,并发是我们利用CPU吞吐量解决大型的、分布式的、复杂的企业级问题的途径。 谁不想自己的应用程序高效高性能呢?是人都想!

虽然确实存在一些人从事并行和并发编程相关工作已经很长时间了,但这其实这并不是普遍现象。 原因之一就是并发编程是有一定的挑战性的。 在传统的多线程并发模型中,程序的执行被分成多个并发运行任务(线程),通过共享内存来交互。 这导致了另人抓狂的竞争条件(race codeition)和死锁问题(deadlock issue),一旦发生,往往需要几周甚至上月的时间去隔离(isolate)、重现(reproduce)和修复(fix)。 显然,开发者很难爱上这种并发模型,我们需要一种更易于编写和维护的并发模型来开发并发程序。

Scala并发采用了完全不同的方法:Actor模型(the Actor model)。 一个actor是一种并行计算的数学模型,它封闭了数据和代码,有自己的线程控制机制,使用不可变(没有副作用)的消息传递(message-passing)技术进行异步通信。 Actor的基本架构依赖于无共享政策(shared-nothing policy),它天生是轻量级的。 于java线程相比,它更像一个被任务调度和执行的事件对象。 Actor模型是一条更好的处理并发问题的途径,无共享架构和异步消息传递技术使得它成为与现存多线程解决方案相比更加容易的一种选择。

Actor模型的历史

Actor模型由Carl Hewitt于1973在他的论文“A Universal Modular ACTOR Formalism for Artificial Intelligence”中首次提出,随后,Gul Agha在他的论文“ACTORS:A Model of Concurrent Computation in Distributed Systems”中加以改进。

Erlang是第一个实现了Actor model的编程语言。Erlang是一种使用动态类型的通用并发编程语言。 随着Erlang并发模型在Ercsson、Facebook和Yahoo!取得成功,它变成了处理并发问题的一种很好的选择,Scala正是继承于它。 在Scala中,actor被设计成一个类库,允许开发者有个自的实现。在第7章和第12章中,你可以看到Scala actor的多种实现。

一般来说,多核处理器编程比单处理器编程要复杂很多,前者需要特定于平台的知识。 不仅如此,多核处理器编程的代码库也比较难维护和管理。 为了简化并行编程,Scala以隐藏了并行算法的并行集合类库的形式提供了更高级别的抽象。 例如,要并行的计算List中每个元素的平方值,你可以这样使用并行集合:

List(1, 2, 3).par.map(x => x * x)

在这个例子中,.par转化List为一个并行集合,这个并行集合实现了一个使用并行算法的map算法。 在内部,这个并行集合类库会利用给定主机的所有可用内核分出所需线程,执行这个map方法。 并行集合类库是Scala的一个新特性,为大多数集合类型提供了并行版本。我将会第4章对并行集体进行探索。

链接