From: Christoph Bauer <ich@christoph-bauer.net>
To: OCaml List <caml-list@inria.fr>
Cc: shootout-list@lists.alioth.debian.org
Subject: Re: [Caml-list] [Benchmark] NBody
Date: Sun, 13 Feb 2005 17:40:52 +0100 [thread overview]
Message-ID: <m3ekfjkw9z.fsf@christoph-bauer.net> (raw)
In-Reply-To: <20050208104312.GA10035@yquem.inria.fr> (Xavier Leroy's message of "Tue, 8 Feb 2005 11:43:12 +0100")
[-- Attachment #1: Type: text/plain, Size: 788 bytes --]
Hi,
>
> The C translation is attached for your amusement.
and here is a mlton version. The test runs on a Pentium-M.
compile flags:
gcc -march=pentium-m -O2 -o nbody-gcc nbody.c
mlton -cc-opt -ffast-math -output nbody-mlton nbody.sml
ocamlopt -ccopt -ffast-math -inline 3 -unsafe -o nbody-ocaml nbody.ml
nbody gcc ocaml mlton
1000 0.000 0.000 0.000
10000 0.014 0.019 0.024
100000 0.070 0.301 0.239
200000 0.231 0.621 0.478
500000 0.552 1.556 1.189
1000000 1.123 3.112 2.377
2000000 2.246 6.229 4.704
3000000 3.367 9.286 8.865
4000000 4.457 12.501 9.687
Christoph Bauer
[-- Attachment #2: nbody.sml --]
[-- Type: application/octet-stream, Size: 4628 bytes --]
val pi = 3.141592653589793
val solar_mass = 4.0 * pi * pi
val days_per_year = 365.24
type planet = {
x : real ref,
y : real ref,
z : real ref,
vx: real ref,
vy: real ref,
vz: real ref,
mass : real
}
fun for (start, stop, f) =
let
fun loop i =
if i > stop
then ()
else (f i; loop (i + 1))
in
loop start
end
fun advance (bodies : planet array) dt =
let
val n = Array.length bodies - 1
in
for (0, n, fn i =>
let
val b = Array.sub (bodies, i)
in
for (i+1, n, fn j =>
let
val b' = Array.sub (bodies, j)
val dx = !(#x b) - !(#x b')
val dy = !(#y b) - !(#y b')
val dz = !(#z b) - !(#z b')
val distance = Math.sqrt(dx * dx + dy * dy + dz * dz)
val mag = dt / (distance * distance * distance)
in
#vx b := !(#vx b) - dx * (#mass b') * mag;
#vy b := !(#vy b) - dy * (#mass b') * mag;
#vz b := !(#vz b) - dz * (#mass b') * mag;
#vx b' := !(#vx b') + dx * (#mass b) * mag;
#vy b' := !(#vy b') + dy * (#mass b) * mag;
#vz b' := !(#vz b') + dz * (#mass b) * mag
end)
end);
for( 0, n, fn i =>
let
val b = Array.sub (bodies, i)
in
#x b := !(#x b) + dt * !(#vx b);
#y b := !(#y b) + dt * !(#vy b);
#z b := !(#z b) + dt * !(#vz b)
end)
end
fun energy (bodies : planet array) =
let
val e = ref 0.0
in
for(0, Array.length bodies - 1, fn i =>
let
val b = Array.sub (bodies, i)
in
e := !e + 0.5 * (#mass b) *
(!(#vx b) * !(#vx b) + !(#vy b)
* !(#vy b) + !(#vz b) * !(#vz b));
for (i+1, Array.length bodies - 1, fn j =>
let
val b' = Array.sub (bodies, j)
val dx = !(#x b) - !(#x b')
val dy = !(#y b) - !(#y b')
val dz = !(#z b) - !(#z b')
val distance = Math.sqrt(dx * dx + dy * dy + dz * dz)
in
e := !e - ((#mass b) * (#mass b')) / distance
end)
end);
!e
end
fun offset_momentum (bodies : planet array) =
let
val px = ref 0.0
val py = ref 0.0
val pz = ref 0.0
in
for (0, Array.length bodies - 1,
fn i =>
(px := !px + !(#vx (Array.sub (bodies, i))) * (#mass (Array.sub (bodies, i)));
py := !py + !(#vy (Array.sub (bodies, i))) * (#mass (Array.sub (bodies, i)));
pz := !pz + !(#vz (Array.sub (bodies, i))) * (#mass (Array.sub (bodies, i)))));
#vx (Array.sub (bodies, 0)) := ~ (!px / solar_mass);
#vy (Array.sub (bodies, 0)) := ~ (!py / solar_mass);
#vz (Array.sub (bodies, 0)) := ~ (!pz / solar_mass)
end
val jupiter = {
x = ref 4.84143144246472090,
y = ref ~1.16032004402742839,
z = ref ~1.03622044471123109e~1,
vx = ref (1.66007664274403694e~3 * days_per_year),
vy = ref (7.69901118419740425e~3 * days_per_year),
vz = ref (~6.90460016972063023e~5 * days_per_year),
mass = 9.54791938424326609e~4 * solar_mass
}
val saturn = {
x = ref 8.34336671824457987,
y = ref 4.12479856412430479e00,
z = ref ~4.03523417114321381e~01,
vx = ref (~2.76742510726862411e~03 * days_per_year),
vy = ref (4.99852801234917238e~03 * days_per_year),
vz = ref (2.30417297573763929e~05 * days_per_year),
mass = 2.85885980666130812e~04 * solar_mass
}
val uranus = {
x = ref 1.28943695621391310e01,
y = ref ~1.51111514016986312e01,
z = ref ~2.23307578892655734e~01,
vx = ref (2.96460137564761618e~03 * days_per_year),
vy = ref (2.37847173959480950e~03 * days_per_year),
vz = ref (~2.96589568540237556e~05 * days_per_year),
mass = 4.36624404335156298e~05 * solar_mass
}
val neptune = {
x = ref 1.53796971148509165e01,
y = ref ~2.59193146099879641e01,
z = ref 1.79258772950371181e~01,
vx = ref (2.68067772490389322e~03 * days_per_year),
vy = ref (1.62824170038242295e~03 * days_per_year),
vz = ref (~9.51592254519715870e~05 * days_per_year),
mass = 5.15138902046611451e~05 * solar_mass
}
val sun = {
x = ref 0.0, y = ref 0.0, z = ref 0.0, vx = ref 0.0, vy = ref 0.0, vz = ref 0.0,
mass= solar_mass
}
fun printr r =
let
val s = Real.fmt (StringCvt.FIX (SOME 9)) r
in (print s; print "\n") end
val bodies = Array.fromList [ sun, jupiter, saturn, uranus, neptune ]
fun main args =
let
val n =
case Int.fromString (List.hd args) of
SOME i => i
| NONE => 0
in
offset_momentum bodies;
printr (energy bodies);
for (1, n, fn _ => advance bodies 0.01);
printr (energy bodies)
end
val _ = main (CommandLine.arguments ())
[-- Attachment #3: Type: text/plain, Size: 172 bytes --]
--
let () = let rec f a w i j = Printf.printf "%.20f\r" a; let a1 = a *. i /. j in
if w then f a1 false (i +. 2.0) j else f a1 true i (j +. 2.0) in f 2.0 false 2.0 1.0
next prev parent reply other threads:[~2005-02-13 15:15 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-02-07 18:57 Christophe TROESTLER
2005-02-07 19:16 ` [Caml-list] " Will M. Farr
2005-02-07 19:36 ` Christophe TROESTLER
2005-02-07 19:55 ` Will M. Farr
2005-02-08 10:34 ` Olivier Andrieu
2005-02-08 10:52 ` Micha
2005-02-07 20:16 ` Markus Mottl
2005-02-07 19:37 ` Martin Jambon
2005-02-07 19:46 ` Christophe TROESTLER
2005-02-07 20:22 ` Martin Jambon
2005-02-07 20:04 ` sejourne_kevin
2005-02-07 20:32 ` Robert Roessler
2005-02-07 22:57 ` Oliver Bandel
2005-02-08 1:29 ` skaller
2005-02-08 1:48 ` Will M. Farr
2005-02-08 9:01 ` Ville-Pertti Keinonen
2005-02-08 9:37 ` skaller
2005-02-08 10:10 ` Ville-Pertti Keinonen
2005-02-08 16:36 ` skaller
2005-02-08 12:04 ` Marcin 'Qrczak' Kowalczyk
2005-02-08 17:06 ` skaller
2005-02-08 10:25 ` Xavier Leroy
2005-02-08 18:34 ` skaller
2005-02-08 10:43 ` Xavier Leroy
2005-02-08 11:26 ` Ville-Pertti Keinonen
2005-02-08 15:59 ` Florian Hars
2005-02-13 16:40 ` Christoph Bauer [this message]
2005-02-13 18:13 ` Christophe TROESTLER
2005-02-24 22:18 ` NBody (one more question) Christophe TROESTLER
2005-02-25 17:06 ` [Caml-list] " John Carr
2005-02-25 17:17 ` Christophe TROESTLER
2005-02-26 16:08 ` John Carr
2005-02-25 17:24 ` Ken Rose
2005-02-25 17:42 ` Oliver Bandel
2005-02-25 17: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=m3ekfjkw9z.fsf@christoph-bauer.net \
--to=ich@christoph-bauer.net \
--cc=caml-list@inria.fr \
--cc=shootout-list@lists.alioth.debian.org \
/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).