窃取工作的并行工作似乎并没有窃取太多工作
Work-stealing parallel job doesn't seem to steal much work
想法是 运行 96 核机器上的并行作业,窃取工作 ForkJoinPool
。
下面是我目前使用的代码:
import scala.collection.parallel.ForkJoinTaskSupport
import scala.concurrent.forkjoin.ForkJoinPool
val sequence: ParSeq[Item] = getItems().par
sequence.tasksupport = new ForkJoinTaskSupport(new ForkJoinPool())
val results = for {
item <- sequence
res = doSomethingWith(item)
} yield res
这里,sequence
有大约 20,000 项。大多数项目需要 2-8 秒来处理,只有大约 200 个需要更长的时间,大约 40 秒。
问题:
一切运行都很好,但是,工作窃取方面似乎效果不佳。以下是随时间变化的预期总 CPU 负载(黑色)与实际负载(蓝色)的比较:
查看 CPU activity 时,很明显随着作业的进行,使用的核心越来越少。最近10分钟,只有2、3个核心还在忙着处理几十个item,一个接一个。
为什么仍在队列中的项目不会被其他空闲核心窃取,即使使用 ForkJoinPool
,这应该是工作窃取?
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html
每个工作线程都有其内部任务队列,可以防止从其他线程窃取工作以限制工作线程之间的交互。
这可能解释了您所看到的行为,尤其是如果您的项目集中出现的长任务不是随机的。
想法是 运行 96 核机器上的并行作业,窃取工作 ForkJoinPool
。
下面是我目前使用的代码:
import scala.collection.parallel.ForkJoinTaskSupport
import scala.concurrent.forkjoin.ForkJoinPool
val sequence: ParSeq[Item] = getItems().par
sequence.tasksupport = new ForkJoinTaskSupport(new ForkJoinPool())
val results = for {
item <- sequence
res = doSomethingWith(item)
} yield res
这里,sequence
有大约 20,000 项。大多数项目需要 2-8 秒来处理,只有大约 200 个需要更长的时间,大约 40 秒。
问题:
一切运行都很好,但是,工作窃取方面似乎效果不佳。以下是随时间变化的预期总 CPU 负载(黑色)与实际负载(蓝色)的比较:
查看 CPU activity 时,很明显随着作业的进行,使用的核心越来越少。最近10分钟,只有2、3个核心还在忙着处理几十个item,一个接一个。
为什么仍在队列中的项目不会被其他空闲核心窃取,即使使用 ForkJoinPool
,这应该是工作窃取?
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html
每个工作线程都有其内部任务队列,可以防止从其他线程窃取工作以限制工作线程之间的交互。
这可能解释了您所看到的行为,尤其是如果您的项目集中出现的长任务不是随机的。