scala_parallelism_concurrency/src/main/scala/scalashop/VerticalBoxBlur.scala
2020-03-01 13:04:59 +01:00

68 lines
2.1 KiB
Scala

package scalashop
import org.scalameter._
object VerticalBoxBlurRunner {
val standardConfig = config(
Key.exec.minWarmupRuns -> 5,
Key.exec.maxWarmupRuns -> 10,
Key.exec.benchRuns -> 10,
Key.verbose -> true
) withWarmer(new Warmer.Default)
def main(args: Array[String]): Unit = {
val radius = 3
val width = 1920
val height = 1080
val src = new Img(width, height)
val dst = new Img(width, height)
val seqtime = standardConfig measure {
VerticalBoxBlur.blur(src, dst, 0, width, radius)
}
println(s"sequential blur time: $seqtime")
val numTasks = 32
val partime = standardConfig measure {
VerticalBoxBlur.parBlur(src, dst, numTasks, radius)
}
println(s"fork/join blur time: $partime")
println(s"speedup: ${seqtime.value / partime.value}")
}
}
/** A simple, trivially parallelizable computation. */
object VerticalBoxBlur extends VerticalBoxBlurInterface {
/** Blurs the columns of the source image `src` into the destination image
* `dst`, starting with `from` and ending with `end` (non-inclusive).
*
* Within each column, `blur` traverses the pixels by going from top to
* bottom.
*/
def blur(src: Img, dst: Img, from: Int, end: Int, radius: Int): Unit = {
// TODO implement this method using the `boxBlurKernel` method
for(x <- from until end){
for(y <- 0 until src.height){
dst(x,y) = boxBlurKernel(src, x, y, radius)
}
}
}
/** Blurs the columns of the source image in parallel using `numTasks` tasks.
*
* Parallelization is done by stripping the source image `src` into
* `numTasks` separate strips, where each strip is composed of some number of
* columns.
*/
def parBlur(src: Img, dst: Img, numTasks: Int, radius: Int): Unit = {
// TODO implement using the `task` construct and the `blur` method
val r = 0 to src.width by (src.width/(Math.min(numTasks, src.width)))
var ranges = r zip r.tail
val tasks = ranges.map( { case (from, to) => task(blur(src, dst, from, to, radius)) } )
tasks foreach {_.join}
}
}