recursiveaction parallelism examples multithreading scala fork-join

multithreading - parallelism - ¿Por qué Scala usa un ForkJoinPool para respaldar su ExecutionContext predeterminado?



forkjoinpool parallelism level (1)

En Scala puede usar un ExecutionContext global si no necesita definir el suyo propio importando scala.concurrent.ExecutionContext.Implicits.global .

Mi pregunta es por ForkJoinPool se eligió ForkJoinPool para este ejecutor en lugar de ThreadPoolExecutor .

Tengo entendido que el marco fork-join es excelente para descomponer problemas recursivamente. Se supone que debes escribir el código que divide una tarea en mitades, de modo que la mitad se pueda ejecutar en subproceso y la otra mitad se pueda ejecutar en otro subproceso. Este parece ser un modelo de programación muy particular y no uno que sea generalmente aplicable al manejo de la ejecución de tareas asíncronas generales en una amplia gama de aplicaciones posibles.

Entonces, ¿por qué se eligió ForkJoinPool para el contexto de ejecución predeterminado que la mayoría de la gente probablemente usará? ¿El diseño de robo de trabajo da como resultado un rendimiento mejorado incluso si no usa el paradigma de unión de horquilla completa?


No puedo hablar por los diseñadores de Scala, pero el uso idiomático de Scala Future a menudo implica la creación de muchas tareas muy pequeñas y de corta duración (por ejemplo, cada llamada a un map crea una nueva tarea), por lo que el diseño de robo de trabajo es apropiado .

Si le interesa este tipo de detalles precisos, es posible que prefiera usar el futuro de scalaz-concurrent, que utiliza trampolines para evitar la creación de tareas adicionales para cada paso del map y hace explícitos los contextos de ejecución (y los valores predeterminados ThreadPoolExecutor un ThreadPoolExecutor ).