First of all, thanks for the example!

Perhaps some one with more experience will provide a better example since I am a complete novice at parallel processing but I offer my example for what it's worth. That said, I was able to almost double the speed (from ~9.5 seconds to ~5.4 seconds) of the rendering on my dual-core laptop using the Task Parallel Library like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#light
#r "System.Core.dll"
#r "System.Threading.dll"
open System
open System.Windows.Forms 
open System.Drawing
open System.Threading

let startTime = DateTime.Now
let height = 800
let width = 1200
let form = new Form(Width = width,
                    Height = height,
                    Text = "Hello Mandelbrot")
                    
let mandelbrot (x,y) = 
    let x0 = ref x
    let y0 = ref y
    let i = ref 0
    while (!x0 * !x0 + !y0 * !y0 < 4.0) && (!i < 1000) do
        let tmpx = !x0 * !x0 - !y0 * !y0 + x    
        let tmpy = 2.0 * !x0 * !y0 + y
        x0 := tmpx
        y0 := tmpy
        i := !i + 1
    1.0 / float (!i + 1)
    
let to_coord x y =
    let scale p0 s = ((float p0) - (float s)/2.0) / (float height / 2.5)
    (scale x width, scale y height)
    
let color x y = int32 (mandelbrot (to_coord x y) |> ( *) 255.0)

type PixelDef = int * int * int

let mutable pixels : PixelDef list = []

let pixLock = new obj()
       
Parallel.For(0, width, (fun x ->
    Parallel.For(0, height, (fun y ->
        lock pixLock (fun () -> pixels <- (x, y, color x y) :: pixels)))
    )
)

let bm = new Bitmap(width, height)
for (x, y, c) in pixels do
    bm.SetPixel(x, y, Color.FromArgb(c, c, c))
       
let canvas = new PictureBox(SizeMode = PictureBoxSizeMode.StretchImage,
                            ClientSize = new Size(width, height),
                            Image = bm)
form.Controls.Add(canvas)

printf "%A\n" (DateTime.Now - startTime)
do Application.Run(form)
By on 12/14/2007 8:29 PM ()

UPDATE: Even though the code I posted above will dish out work to multiple processors, it appears that the speed increase may mostly be due to a code change that I made.

The original example calls the c function three times for each pixel. I made a few revisions in my example and one of those revisions was to only call the c function once per pixel. This appears to be the main source of the speed increase.

I did warn that I was a novice! [;)]

By on 12/15/2007 4:59 AM ()

Really??

[:$] [:$] [:$]

I thougth that calling the function with the same args would evaluate it just once. There are no side effects on the function. Is'nt the compiler capable to check this?
I have to do some experimentation :P... I think (and maybe I'm wrong) that haskell would evaluate the function just once... maybe for haskell is easier since is pure ... there are no side effects.

Another thing... Just in this case is the lock necessary?

By on 12/17/2007 9:31 AM ()

I changed this part of the code and really makes a difference

1
2
3
4
5
6
7
8
9
let c x y = Int32.of_float(mandelbrot (to_coord x y) |> ( *) 255.0)
let setpix x y t = bm.SetPixel(x, y, Color.FromArgb(t,t,t))
for i in [0..(width - 1)] do 
  for j in [0..(height -1)] do
    let color = c i j
    setpix i j color
canvas.ClientSize <- new Size(width,height)
canvas.Image <- bm 
form.Controls.Add(canvas)    


But now I don't understand Why this 2 cases are so different:

1
2
3
4
5
6
7
8
let one = (printf "I'm being evaluated\n"; 1)

let number n:int = (printf "I'm being evaluated\n"; n)

let two = printf "I'm number %d\n" (one + one)

let twoprime = printf "I'm number %d\n" (number 1 + number 1)

Anyone has some further reading to stop doing dumb questions?

(PS: anyone is having problems with the design option? it keeps

changing my font size... and every time I paste something to the Design window

it freeze up my Browser :S)

By on 12/17/2007 12:28 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper