【发布时间】:2011-09-02 12:02:34
【问题描述】:
我最近发现了 Scala 2.9 中的 Parallel Collection,并且很高兴看到可以使用 collection.parallel.ForkJoinTasks.defaultForkJoinPool.setParallelism 设置并行度。
但是,当我尝试添加两个大小为一百万的向量的实验时,我发现
- 使用并行收集并将并行度设置为 64 与顺序收集一样快(显示在结果中)。
- 增加 setParallelism 似乎会以非线性方式提高性能。我至少会有预期的单调行为(也就是说,如果我增加并行度,性能不会降低)
谁能解释一下为什么会这样
object examplePar extends App{
val Rnd = new Random()
val numSims = 1
val x = for(j <- 1 to 1000000) yield Rnd.nextDouble()
val y = for(j <- 1 to 1000000) yield Rnd.nextDouble()
val parInt = List(1,2,4,8,16,32,64,128,256)
var avg:Double = 0.0
var currTime:Long = 0
for(j <- parInt){
collection.parallel.ForkJoinTasks.defaultForkJoinPool.setParallelism(j)
avg = 0.0
for (k <- 1 to numSims){
currTime = System.currentTimeMillis()
(x zip y).par.map(x => x._1 + x._2)
avg += (System.currentTimeMillis() - currTime)
}
println("Average Time to execute with Parallelism set to " + j.toString + " = "+ (avg/numSims).toString + "ms")
}
currTime = System.currentTimeMillis()
(x zip y).map(x => x._1 + x._2)
println("Time to execute using Sequential = " + (System.currentTimeMillis() - currTime).toString + "ms")
}
使用 Scala 2.9.1 和四核处理器运行示例的结果是
Average Time to execute with Parallelism set to 1 = 1047.0ms
Average Time to execute with Parallelism set to 2 = 594.0ms
Average Time to execute with Parallelism set to 4 = 672.0ms
Average Time to execute with Parallelism set to 8 = 343.0ms
Average Time to execute with Parallelism set to 16 = 375.0ms
Average Time to execute with Parallelism set to 32 = 391.0ms
Average Time to execute with Parallelism set to 64 = 406.0ms
Average Time to execute with Parallelism set to 128 = 813.0ms
Average Time to execute with Parallelism set to 256 = 469.0ms
Time to execute using Sequential = 406ms
虽然这些结果是针对一次运行的,但在多次运行的平均时它们是一致的
【问题讨论】:
-
如果您尝试设置比可用处理器更多的并行度,您将让这些东西彼此串行运行,但仍需支付并行度税。