Вкратце, есть два ортогональных аспекта того, как ваши операции распараллеливаются:
- Степень, в которой ваша коллекция разбивается на куски (т.е. размер кусков) для распараллеливаемой операции (например,
map
или filter
)
- Количество потоков, используемых для базового пула fork-join (для которого выполняются параллельные задачи)
Для # 2 это управляется самим пулом, который обнаруживает «идеальный» уровень параллелизма во время выполнения (см. java.lang.Runtime.getRuntime.availableProcessors
)
Для # 1 это отдельная проблема, и API параллельных коллекций Scala делает это через концепцию похищения работ ( адаптивное планирование ). То есть, когда определенная часть работы выполнена, работник попытается украсть работу из других рабочих очередей. Если ни один из них не доступен, это свидетельствует о том, что все процессоры очень заняты, и, следовательно, следует выполнить большую часть работы.
Александр Прокопец, который внедрил библиотеку, выступил с докладом на ScalaDays этого года, который скоро будет онлайн. Он также дал отличный доклад на ScalaDays2010 , где он подробно описывает, как операции разделяются и объединяются (есть ряд проблем, которые не сразу очевидны, и некоторые приятные моменты и там сообразительности!).
Более подробный ответ доступен в PDF, описывающем API параллельных коллекций .