The above image is the output of the following scala program
import java.awt.image.BufferedImage import java.awt.Color import java.awt.Dimension import java.awt.Graphics2D import scala.swing.MainFrame import scala.swing.Panel import scala.swing.SimpleSwingApplication object Mandelbrot extends SimpleSwingApplication { val ER = 4.0 // escape radius val maxIter = 50000 // max iteration val N = 1000 // image dimension def top = new MainFrame { title = "Mandelbrot Set" contents = new Panel { override protected def paintComponent(g: Graphics2D) = { super.paintComponent(g) var start = System.currentTimeMillis() g setColor Color.BLACK var image = new BufferedImage(N, N, BufferedImage.TYPE_INT_RGB) var m = new Mandelbrot(N, ER, maxIter, 1) for { i <- 0 until N j <- 0 until N } image.setRGB(i, j, m.pms(i * N + j)) g.drawImage(image, 0, 0, null) println(System.currentTimeMillis() - start) } } size = new Dimension(N, N) } } class Mandelbrot(n: Int, er: Double, maxIter: Int, zoom: Int) { val pms = (0 to n * n).map { (x => computeColor(x / n, x % n)) } // work gets done here def computeColor(x: Int, y: Int): Int = { var (i, zx, zy) = (0, 0.0, 0.0) val cx = -2.5 + x * (er / n) / zoom val cy = 2 - y * (er / n) / zoom while (zx * zx + zy * zy < er && i < maxIter) { val temp = zx * zx - zy * zy + cx zy = 2 * zx * zy + cy; zx = temp; i = i + 1; } if (i == maxIter) Color.BLACK.getRGB() else (Color.getHSBColor(i / 20.0F, 1F, 1F)).getRGB() } }
It took over 22.811 second to generate 1000 by 1000 fractal image, the max iteration is set at 50000 per pixel. This is without parallelization. So let's introduce parallel processing to the program with one line of change. Made the following change to line 40 to the above code.
// Before val pms = (0 to n * n).map { (x => computeColor(x / n, x % n)) } // work gets done here // After val pms = (0 to n * n).par.map { (x => computeColor(x / n, x % n)) } // work gets done here // notice the extra method call par after the list
The new fractal image took only 3.771 second to generate, over 6 fold increase.
Notice that all 8 cores of my i7-2600K CPU is pulling its weight. A simple method call par after a collection gives you the power of parallelism, try that in Java. Here’s a video of Aleksandar Prokopec explaining parallel collections at Scala Days 2010
No comments:
Post a Comment