Scala如何实现并行性?

时间:2013-09-13 19:22:36

标签: scala akka multicore actor actor-model

我正在学习分布式系统课程,我们必须使用Scala制作我们的项目。我们的讲师告诉我们,Scala在使用多个内核进行计算并使用并行性来解决问题同时与actor模型集成的意义上是好的。

这是一个理论问题。我已经学习了一些关于使用Akka的actor模型的基础知识,我的问题是,在编程时,用户是否必须向编译器提供详细信息,以便各个actor在多个内核上工作,或者Scala是否会处理它并使用多个各种演员的核心?

简而言之,我的问题是:当我们在Scala中使用Akka库声明多个actor时,Scala编译器是否会自动使用多核CPU功能在内核之间分配各种actor,或者程序员是否必须提供一些输入这样做?

2 个答案:

答案 0 :(得分:23)

TL; DR:使用Akka中的默认配置,您无需为大多数用例提供相当好的并行性。

更长的答案: Akka中的参与者在Dispatcher上运行,并且Dispatcher有一个ExecutionService,它通常是一个Threads池。线程数由开发人员配置,但默认情况下是计算机上CPU核心数的3倍(请参阅参考配置中的default-dispatcher.parallelism-factor here)。

在任何时候,每个CPU核心都可以使用其中一个线程运行Actor,因此如果Dispatcher的ExecutionService中有许多线程等于CPU上的核心数,那么你将能够利用所有核心。将其设置为默认配置中核心数的三倍的原因是为了补偿阻塞IO。

IO很慢,并且在您执行IO而不是使用CPU时阻塞调用hog线程。因此,获得最佳并行级别的关键是配置此线程池:

  • 如果您只进行非阻塞IO,则可以将其设置为您拥有的CPU核心数,并确信您正在充分利用CPU。
  • 你做的阻塞IO越多,你需要越多的线程来保持良好的并行性,但要注意 - 你使用的线程越多,你将使用的内存越多,而且线程不是世界上最轻量级的东西。

答案 1 :(得分:11)

theon的答案非常好,但我想指出演员不是在Scala中实现并行性的唯一方法。如果您不需要管理状态,Futures通常是一种更简单的并行执行计算的方法。您只需在调用Future工厂函数时包装可以独立于其他代码运行的每段代码,然后您可以使用对{{1}的调用来编译/转换每个代码段的结果(也是并行) },mapflatMap等,或fold理解。您需要配置的所有内容都是for作为ExecutionContext,如果您已经在使用Akka,则可以使用与您使用的相同的一个,或者您可以使用预配置的全局默认值。