How does Scala attain parallelism?
Asked Answered
H

2

13

I am taking a course on distributed systems and we have to make our project using Scala. Our instructor told us that Scala is good in the sense that it uses multiple cores to do the computation and uses parallelism to solve problems while being integrated with the actor model.

This is a theoretical question. I have learned some basics about the actor model using Akka and my question is that, while programming, does the user have to provide the details to the compiler so that various actors work on multiple cores, or does Scala take care of that and use multiple cores for various actors?

In a nutshell my question is: when we declare multiple actors using the Akka libraries in Scala, does Scala compiler automatically use the multi-core CPU power to distribute various actors among cores, or does the programmer have to provide some input to do this?

Holguin answered 13/9, 2013 at 19:22 Comment(0)
S
23

TL;DR: With the default configuration in Akka you need do nothing to get pretty good parallelism for most use cases.

Longer Answer: Actors in Akka run on a Dispatcher and that Dispatcher has an ExecutionService which is typically a pool of Threads. The number of Threads is configured by the developer, but by default is 3 times the number of CPU cores on the machine (see default-dispatcher.parallelism-factor here in the reference configuration).

At any point in time each CPU core can be running an Actor using one of these threads, so provided you have a number of threads in your Dispatcher's ExecutionService that is equal to the number of cores on your CPU, you will be able to take advantage of all your cores. The reason that this is set to three times the number of cores in the default configuration is to compensate for blocking IO.

IO is slow, and blocking calls hog threads at times you are doing IO rather than using the CPU. So the key to getting the best level of parallelism is configuring this thread pool:

  • If you are doing only non-blocking IO, you can set it to the number of CPU cores you have and feel confident you are taking full advantage of your CPU.
  • The more blocking IO you do, the more threads you will need to keep getting good parallelism, but be warned - the more Threads you use, the more memory you will use and Threads are not the most lightweight things in the world.
Sniper answered 13/9, 2013 at 19:28 Comment(2)
Thanks for fast reply so does that mean AKKA dispatcher takes care of parallelism and user is only required to provide number of actors (or threads) while programming?Holguin
Make as many Actors as you need. The number of threads is the thing you need to tune for the best parallelism. If you are doing only non-blocking IO, set it to the number of CPU cores you have. The more blocking IO you do, the more threads you will need to keep getting good parallelism. But yes, with the default configuration you need do nothing to get pretty good parallelism for most use cases.Sniper
D
11

theon's answer is pretty good, but I would just like to point out that actors are not the only way to achieve parallelism in Scala. If you do not need to manage state, Futures are generally a simpler way to perform computation in parallel. You just wrap each snippet of code that can run independently of others in a call to the Future factory function, and you can then compose/transform the results of each snippet (also in parallel) using calls to map, flatMap, fold, etc., or with for comprehensions. All you need to configure is an ExecutionContext as an implicit val, and if you are already using Akka, you can use the same one that your actors use, or you can use the preconfigured global default.

Doloritas answered 16/9, 2013 at 23:54 Comment(1)
Good point. It's worth also mentioning parallel collections. Simply add an in-scope ExecutionContext as you have mentioned and then change any calls from coll.map, coll.filter, etc to coll.par.map and coll.par.filter for instant parallelism.Sniper

© 2022 - 2024 — McMap. All rights reserved.