我正在使用我正在重构的个人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 数组的访问,导致阻塞状态?因为我只以只读方式使用它,我相信它是线程安全的。 我有点困惑......