caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: wester@ilt.fhg.de
To: caml-list@inria.fr
Subject: Floating point array computations
Date: Thu, 25 Jan 2001 11:34:32 +0100	[thread overview]
Message-ID: <200101251034.LAA06543@ilt.fhg.de> (raw)

Hi,

I'm a OCmal beginner and would like to use it for some numerical
computations. Speed is not the only criterion but for number crunching it
is an important point. So I would like to make my OCaml code as fast 
as possible. I have tried some small examples (source attached below) 
and have some questions. 

In sample code form the ICFP 200 contest I found:

type v = float array

is array a build in type?

The functions main1 .. main4 below do the same but take different time for it
(compiled with ocamlopt). I expected main2 to be the fastest but main3 is 
fastest. main3 300 300 1000 takes on my PC (450 Mhz PI, 520 MB RAM) 
26 sec, this is about twice the time of C++ and about the same as Java.

Can somone tell me why main3 is faster than main2 (36 sec) although
main3 makes function calls to step?

I also tried Array.unsafe_get/set in main4. I expected this to be even faster
because I have seen it in the ICFP contest sample code. But actually 
it is much slower (about 100 sec). Did I make anything wrong?

Would Bigarray perform better? 

I would be very appriciative for your help to clarify this points.

Thank you in advance.

Rolf


-----------------------------------------------------------------------------------------------------------

let main1 nx ny nt =
    let matrix1 = Array.make_matrix nx ny 0.0 in
    let matrix2 = Array.make_matrix nx ny 0.0 in
    let sum   = ref 0  in
    let start = ref 0. in
    let upper_idx = Array.length matrix1 - 1 in
    for r = 1 to nt do
        for i = 1 to upper_idx - 1  do
		  let mat2  = matrix2.(i)   and
		      mat1m = matrix1.(i-1) and
			  mat10 = matrix1.(i)   and
			  mat1p = matrix1.(i+1) in
            for j = 1 to upper_idx - 1 do
                mat2.(j) <- mat10.(j) +. 1.0  +.
				                0.1*.(mat1p.(j)   +.
                                      mat1m.(j)   +.
                                      mat10.(j+1) +.
                                      mat10.(j-1) -.
                               4.0 *. mat10.(j));
            done;
        done;
        for i = 1 to upper_idx - 1  do
            for j = 1 to upper_idx - 1 do
                matrix1.(i).(j) <- matrix2.(i).(j) +. 1.0 +.
				0.1*.(matrix2.(i+1).(j) +.
                                      matrix2.(i-1).(j) +.
                                      matrix2.(i).(j+1) +.
                                      matrix2.(i).(j-1) -.
                                   4.0 *. matrix2.(i).(j));
            done;
        done;
	Printf.printf "%f\n" (matrix1.(150).(150));
	flush stdout;
    done;
;;


let main2 nx ny nt =
    let matrix1 = Array.make_matrix nx ny 0.0 in
    let matrix2 = Array.make_matrix nx ny 0.0 in
    let sum   = ref 0  in
    let start = ref 0. in
    let upper_idx = Array.length matrix1 - 1 in
    for r = 1 to nt do
        for i = 1 to upper_idx - 1  do
		  let mat2  = matrix2.(i)   and
		      mat1m = matrix1.(i-1) and
			  mat10 = matrix1.(i)   and
			  mat1p = matrix1.(i+1) in
              for j = 1 to upper_idx - 1 do
                mat2.(j) <- mat10.(j) +. 1.0  +.
				                0.1*.(mat1p.(j)   +.
                                      mat1m.(j)   +.
                                      mat10.(j+1) +.
                                      mat10.(j-1) -.
                               4.0 *. mat10.(j));
            done;
        done;
        for i = 1 to upper_idx - 1  do
		  let mat2  = matrix1.(i)   and
		      mat1m = matrix2.(i-1) and
			  mat10 = matrix2.(i)   and
			  mat1p = matrix2.(i+1) in
              for j = 1 to upper_idx - 1 do
                mat2.(j) <- mat10.(j) +. 1.0  +.
				                0.1*.(mat1p.(j)   +.
                                      mat1m.(j)   +.
                                      mat10.(j+1) +.
                                      mat10.(j-1) -.
                               4.0 *. mat10.(j));
            done;
        done;
	Printf.printf "%f\n" (matrix1.(nx / 2).(ny / 2));
	flush stdout;
    done;
;;

let main3 nx ny nt =
  let step nmax m1p m1m m10 m2 =
     for j = 1 to nmax - 1 do
          m2.(j) <- m10.(j) +. 1.0  +.
				   0.1*.(m1p.(j)   +.
                         m1m.(j)   +.
                         m10.(j+1) +.
                         m10.(j-1) -.
                  4.0 *. m10.(j));
      done;
	in
    let matrix1 = Array.make_matrix nx ny 0.0 in
    let matrix2 = Array.make_matrix nx ny 0.0 in
    let sum   = ref 0  in
    let start = ref 0. in
    let upper_idx = Array.length matrix1 - 1 in
    for r = 1 to nt do
        for i = 1 to upper_idx - 1  do
		  let mat2  = matrix2.(i)   and
		      mat1m = matrix1.(i-1) and
			  mat10 = matrix1.(i)   and
			  mat1p = matrix1.(i+1) in
		  step upper_idx mat1p mat1m mat10 mat2;
        done;
        for i = 1 to upper_idx - 1  do
		  let mat2  = matrix1.(i)   and
		      mat1m = matrix2.(i-1) and
			  mat10 = matrix2.(i)   and
			  mat1p = matrix2.(i+1) in
		  step upper_idx mat1p mat1m mat10 mat2;
        done;
	Printf.printf "%f\n" (matrix1.(nx / 2).(ny / 2));
	flush stdout;
    done;
;;


let uset = Array.unsafe_set;;
let uget = Array.unsafe_get;;

let main4 nx ny nt =
  let step nmax m1p m1m m10 m2 =
     for j = 1 to nmax - 1 do
          uset m2 j  ((uget m10 j) +. 1.0  +.
				             0.1*.((uget m1p j    ) +.
                                   (uget m1m j    ) +.
                                   (uget m10 (j+1)) +.
                                   (uget m10 (j-1)) -.
                            4.0 *. (uget m10 j    )    ));
      done;
	in
    let matrix1 = Array.make_matrix nx ny 0.0 in
    let matrix2 = Array.make_matrix nx ny 0.0 in
    let sum   = ref 0  in
    let start = ref 0. in
    let upper_idx = Array.length matrix1 - 1 in
    for r = 1 to nt do
        for i = 1 to upper_idx - 1  do
		  let mat2  = matrix2.(i)   and
		      mat1m = matrix1.(i-1) and
			  mat10 = matrix1.(i)   and
			  mat1p = matrix1.(i+1) in
		  step upper_idx mat1p mat1m mat10 mat2;
        done;
        for i = 1 to upper_idx - 1  do
		  let mat2  = matrix1.(i)   and
		      mat1m = matrix2.(i-1) and
			  mat10 = matrix2.(i)   and
			  mat1p = matrix2.(i+1) in
		  step upper_idx mat1p mat1m mat10 mat2;
        done;
	Printf.printf "%f\n" (matrix1.(nx / 2).(ny / 2));
	flush stdout;
    done;
;;

let _ = main3 300 300 1000;;


-------------------------------------
Rolf Wester
wester@ilt.fhg.de



             reply	other threads:[~2001-01-26 21:03 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-01-25 10:34 wester [this message]
2001-02-01 13:57 ` Xavier Leroy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200101251034.LAA06543@ilt.fhg.de \
    --to=wester@ilt.fhg.de \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).