From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Delivered-To: caml-list@yquem.inria.fr Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 15904BC88 for ; Mon, 7 Feb 2005 19:57:29 +0100 (CET) Received: from pauillac.inria.fr (pauillac.inria.fr [128.93.11.35]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id j17IvScA032565 for ; Mon, 7 Feb 2005 19:57:28 +0100 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id TAA12564 for ; Mon, 7 Feb 2005 19:57:28 +0100 (MET) Received: from hedwig1.umh.ac.be (hedwig2.umh.ac.be [193.190.193.73]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id j17IvRif032558 for ; Mon, 7 Feb 2005 19:57:28 +0100 Received: from poincare (mail@poincare.swapping.umh.ac.be [10.102.100.13]) by hedwig1.umh.ac.be (8.13.1/8.13.1) with ESMTP id j17J0uLo1331386; Mon, 7 Feb 2005 20:00:58 +0100 Received: from poincare ([127.0.0.1] helo=localhost ident=trch) by poincare with esmtp (Exim 3.36 #1 (Debian)) id 1CyE4a-0006Xf-00; Mon, 07 Feb 2005 19:57:24 +0100 Date: Mon, 07 Feb 2005 19:57:24 +0100 (CET) Message-Id: <20050207.195724.87945401.Christophe.Troestler@umh.ac.be> To: "O'Caml Mailing List" Subject: [Benchmark] NBody From: Christophe TROESTLER Organization: Universite de Mons-Hainaut (http://math.umh.ac.be/an/) X-Spook: bullion FTS2000 unclassified BRLO Ft. Meade AK-47 FSF blackjack South Africa Dateline X-Blessing: Om Ah Hum Vajra Guru Pema Siddhi Hum X-Operating-System: GNU/Linux (http://www.linux.org/) X-Mailer-URL: http://www.mew.org/ X-Mailer: Mew version 4.2rc1 on Emacs 21.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Multipart/Mixed; boundary="--Next_Part(Mon_Feb__7_19_57_24_2005_233)--" Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.1 (www dot roaringpenguin dot com slash mimedefang) X-Miltered: at concorde with ID 4207BA18.003 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Miltered: at concorde with ID 4207BA18.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; christophe:01 troestler:01 christophe:01 troestler:01 umh:01 ocamlopt:01 -inline:01 -unsafe:01 ocaml:01 ocaml:01 mutable:01 mutable:01 sqrt:01 sqrt:01 argv:01 X-Attachments: name="nbody.ml" X-Spam-Checker-Version: SpamAssassin 3.0.2 (2004-11-16) on yquem.inria.fr X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.0.2 X-Spam-Level: ----Next_Part(Mon_Feb__7_19_57_24_2005_233)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, For fun I have implemented an nbody simulation following http://shootout.alioth.debian.org/benchmark.php?test=nbody&lang=all&sort=cpu (code is attached). I've compiled it with ocamlopt -o nbody.com -inline 3 -unsafe -ccopt -O2 nbody.ml I've compared with the Java program they give. I get (on a Pentium(R) 4 CPU 2.40GHz Debian): n OCaml Java 1000 0.004 0.112 10000 0.016 0.112 100000 0.159 0.218 200000 0.284 0.370 500000 0.707 0.702 1000000 1.410 1.359 2000000 2.884 2.453 3000000 4.294 3.590 4000000 5.735 4.774 I am interested in explanations why OCaml seems asymptotically slower than Java and ways to improve that. My concern is actually not so much for the shootout as for my own numerical programs. Regards, ChriS ----Next_Part(Mon_Feb__7_19_57_24_2005_233)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="nbody.ml" (* http://shootout.alioth.debian.org/benchmark.php?test=nbody&lang=all&sort=cpu *) let pi = 3.141592653589793 let solar_mass = 4. *. pi *. pi let days_per_year = 365.24 type planet = { mutable x : float; mutable y : float; mutable z : float; mutable vx: float; mutable vy: float; mutable vz: float; mass : float; } let advance bodies dt = let n = Array.length bodies - 1 in for i = 0 to n do let b = bodies.(i) in for j = i+1 to n do let b' = bodies.(j) in let dx = b.x -. b'.x and dy = b.y -. b'.y and dz = b.z -. b'.z in let distance = sqrt(dx *. dx +. dy *. dy +. dz *. dz) in let mag = dt /. (distance *. distance *. distance) in b.vx <- b.vx -. dx *. b'.mass *. mag; b.vy <- b.vy -. dy *. b'.mass *. mag; b.vz <- b.vz -. dz *. b'.mass *. mag; b'.vx <- b'.vx +. dx *. b.mass *. mag; b'.vy <- b'.vy +. dy *. b.mass *. mag; b'.vz <- b'.vz +. dz *. b.mass *. mag; done done; for i = 0 to n do let b = bodies.(i) in b.x <- b.x +. dt *. b.vx; b.y <- b.y +. dt *. b.vy; b.z <- b.z +. dt *. b.vz; done let energy bodies = let e = ref 0. in for i = 0 to Array.length bodies - 1 do let b = bodies.(i) in e := !e +. 0.5 *. b.mass *. (b.vx *. b.vx +. b.vy *. b.vy +. b.vz *. b.vz); for j = i+1 to Array.length bodies - 1 do let b' = bodies.(j) in let dx = b.x -. b'.x and dy = b.y -. b'.y and dz = b.z -. b'.z in let distance = sqrt(dx *. dx +. dy *. dy +. dz *. dz) in e := !e -. (b.mass *. b'.mass) /. distance done done; !e let offset_momentum bodies = let px = ref 0. and py = ref 0. and pz = ref 0. in for i = 0 to Array.length bodies - 1 do px := !px +. bodies.(i).vx *. bodies.(i).mass; py := !py +. bodies.(i).vy *. bodies.(i).mass; pz := !pz +. bodies.(i).vz *. bodies.(i).mass; done; bodies.(0).vx <- -. !px /. solar_mass; bodies.(0).vy <- -. !py /. solar_mass; bodies.(0).vz <- -. !pz /. solar_mass let jupiter = { x = 4.84143144246472090e+00; y = -1.16032004402742839e+00; z = -1.03622044471123109e-01; vx = 1.66007664274403694e-03 *. days_per_year; vy = 7.69901118419740425e-03 *. days_per_year; vz = -6.90460016972063023e-05 *. days_per_year; mass = 9.54791938424326609e-04 *. solar_mass; } let saturn = { x = 8.34336671824457987e+00; y = 4.12479856412430479e+00; z = -4.03523417114321381e-01; vx = -2.76742510726862411e-03 *. days_per_year; vy = 4.99852801234917238e-03 *. days_per_year; vz = 2.30417297573763929e-05 *. days_per_year; mass = 2.85885980666130812e-04 *. solar_mass; } let uranus = { x = 1.28943695621391310e+01; y = -1.51111514016986312e+01; z = -2.23307578892655734e-01; vx = 2.96460137564761618e-03 *. days_per_year; vy = 2.37847173959480950e-03 *. days_per_year; vz = -2.96589568540237556e-05 *. days_per_year; mass = 4.36624404335156298e-05 *. solar_mass; } let neptune = { x = 1.53796971148509165e+01; y = -2.59193146099879641e+01; z = 1.79258772950371181e-01; vx = 2.68067772490389322e-03 *. days_per_year; vy = 1.62824170038242295e-03 *. days_per_year; vz = -9.51592254519715870e-05 *. days_per_year; mass = 5.15138902046611451e-05 *. solar_mass; } let sun = { x = 0.; y = 0.; z = 0.; vx = 0.; vy = 0.; vz = 0.; mass= solar_mass; } let bodies = [| sun; jupiter; saturn; uranus; neptune |] let () = let n = int_of_string(Sys.argv.(1)) in offset_momentum bodies; Printf.printf "%.9f\n" (energy bodies); for i = 1 to n do advance bodies 0.01 done; Printf.printf "%.9f\n" (energy bodies) ----Next_Part(Mon_Feb__7_19_57_24_2005_233)----