并行和顺序Scala集合之间的映射操作的差异

时间:2017-08-20 20:35:06

标签: multithreading scala collections concurrency parallel-processing

我正在使用我正在重构的个人Java图像处理代码编写一个Scala小片段来测试我的机器上并行和程序Scala集合的性能差异。 但是,我遇到了一个奇怪的问题,即在并行集合中使用map(在本例中为ParArray):计算似乎没有开始(程序不会停止进入getBrightness def)。我似乎进入阻止状态。

以下是代码:

def getBrightness(bright: Array[Float], kernel : Array[Array[Float]], kernelSize : Int, normFactor : Float, x : Int, y : Int) : Float = {
    var brightness : Float = 0
    for(dx <- -(kernelSize / 2) to kernelSize / 2){
      for(dy <- -(kernelSize / 2) to kernelSize / 2){
        val kerVal = kernel(kernelSize / 2 + dx)(kernelSize / 2 + dy)
        brightness += bright(index(dx + x, dy + y)) * kerVal
      }
    }
    brightness / normFactor
}

  def convolute(pixels : ParArray[Color], kernel : Array[Array[Float]]) : ParArray[Color] = {
    val bright : Array[Float] = pixels.map(c => Color.RGBtoHSB(c.getRed, c.getBlue, c.getGreen, null)(2)).toArray

    val normFactor : Float= kernel.toList.flatten.sum
    pixels.zipWithIndex
          .map{case(_ , idx) => getBrightness(bright, kernel, kernel.length, normFactor, idx % imgWidth, idx / imgWidth)}
          .map(Color.getHSBColor(0, 0, _))
}

对于我对并行集合的理解肯定是一个问题,如果我将集合更改为如下的顺序数组:

  pixels.zipWithIndex
          .seq //switching to sequential collection
          .map{case(_ , idx) => getBrightness(bright, kernel, kernel.length, normFactor, idx % imgWidth, idx / imgWidth)}
          .map(Color.getHSBColor(0, 0, _))
          .par
}

然后一切顺利,进行卷积。我也知道问题来自地图内的getBrightness调用,因为我的调试器循环它并且从不执​​行def本身,即从不输入getBrightness定义。 它是否来自 bright 数组的访问,导致阻塞状态?因为我只以只读方式使用它,我相信它是线程安全的。 我有点困惑......

0 个答案:

没有答案