Revision c08d3a19e62d40d4e101d1fe6b8441ed91023613 authored by Roberto Di Cosmo on 07 November 2011, 20:36:57 UTC, committed by Roberto Di Cosmo on 07 November 2011, 20:36:57 UTC
1 parent 8b7eed8
Raw File
mandels.ml
(**************************************************************************)
(* Sample use of ParMap,  a simple library to perform Map computations on *)
(* a multi-core                                                           *)
(*                                                                        *)
(*  Author(s):  Marco Danelutto and Roberto Di Cosmo                      *)
(*                                                                        *)
(*  This program is free software: you can redistribute it and/or modify  *)
(*  it under the terms of the GNU General Public License as               *)
(*  published by the Free Software Foundation, either version 2 of the    *)
(*  License, or (at your option) any later version.                       *)
(**************************************************************************)

open Graphics;;

let n   = 1000;; (* the size of the square screen windows in pixels      *)
let res = 1000;; (* the resolution: maximum number of iterations allowed *)

(* convert an integer in the range 0..res into a screen color *)

let color_of c res = Pervasives.truncate 
      (((float c)/.(float res))*.(float Graphics.white));;

(* compute the color of a pixel by iterating z_n+1=z_n^2+c *)
(* j,k are the pixel coordinates                           *)

let pixel (j,k,res,n) = 
  let zr = ref 0.0 in
  let zi = ref 0.0 in
  let cr = ref 0.0 in
  let ci = ref 0.0 in
  let zrs = ref 0.0 in
  let zis = ref 0.0 in
  let d   = ref (2.0 /. ((float  n) -. 1.0)) in
  let colour = Array.create n (Graphics.black) in

  for s = 0 to (n-1) do
    let j1 = ref (float  j.(s)) in
    let k1 = ref (float  k) in
    begin
      zr := !j1 *. !d -. 1.0;
      zi := !k1 *. !d -. 1.0;
      cr := !zr;
      ci := !zi;
      zrs := 0.0;
      zis := 0.0;
      for i=0 to (res-1) do
	begin
	  if(not((!zrs +. !zis) > 4.0))
	  then 
	    begin
	      zrs := !zr *. !zr;
	      zis := !zi *. !zi;
	      zi  := 2.0 *. !zr *. !zi +. !ci;
	      zr  := !zrs -. !zis +. !cr;
	      Array.set colour s (color_of i res);
	    end;
    	end
      done
    end
  done;
  (colour,k);;

(* draw a line on the screen using fast image functions *)

let show_a_result r =
  match r with
    (col,j) ->
      draw_image (make_image [| col |]) 0 j;;

(* generate the initial configuration *)

let initsegm n = 
  let rec aux acc = function 0 -> acc | n -> aux (n::acc) (n-1) in
  aux [] n
;;

let tasks = 
  let ini = Array.create n 0 in
  let iniv = 
    for i=0 to (n-1) do
      Array.set ini i i
    done; ini in
  List.map (fun seed -> (iniv,seed,res,n)) (initsegm n)
;;

let draw res =
  open_graph (" "^(string_of_int n)^"x"^(string_of_int n));
  List.iter show_a_result res; close_graph();;

(* compute the image *)

let tseq,m=
  let d=Unix.gettimeofday() in
  let res = (List.map pixel tasks) in
  (Unix.gettimeofday() -. d),res
;;

Printf.printf "Sequential time: %f\n" tseq;;

let scale_test iter tseq nprocmin nprocmax =
Printf.eprintf "Testing scalability with %d iterations on %d*2 to %d*2 cores\n" iter nprocmin nprocmax;
  for i = nprocmin to nprocmax do
    let tot=ref 0.0 in
    for j=1 to iter do
      let d=Unix.gettimeofday() in
      ignore(Parmap.parmap  ~ncores:i pixel (Parmap.L tasks));
      tot:=!tot+.(Unix.gettimeofday()-.d)
    done;
    let speedup=tseq /. (!tot /. (float iter)) in 
    Printf.eprintf "Speedup with %d cores (average on %d iterations): %f (tseq=%f, tpar=%f)\n" (i*2) iter speedup tseq (!tot /. (float iter))
  done
;;

scale_test 2 tseq 1 4;;

draw m;;

ignore(input_line stdin);;

back to top