/mobile Handheld Friendly website

 performance measurements

Each table row shows performance measurements for this ATS program with a particular command-line input value N.

 N  CPU secs Elapsed secs Memory KB Code B ≈ CPU Load
500,0000.210.223161920  0% 5% 0% 95%
5,000,0002.072.083201920  0% 0% 1% 100%
50,000,00020.6520.653201920  0% 1% 0% 100%

Read the ↓ make, command line, and program output logs to see how this program was run.

Read n-body benchmark to see what this program should do.

 notes

ATS/Anairiats version 0.2.8

 n-body ATS #2 program source code

(*
** The Computer Language Benchmarks Game
** http://benchmarksgame.alioth.debian.org/
**
** contributed by Hongwei Xi
**
** compilation command:
**   atscc -msse2 -mfpmath=sse -O3 n-body.dats -o n-body -lm
*)

(* ****** ****** *)

staload "libc/SATS/math.sats"

(* ****** ****** *)

typedef planet = @{
  x= double, y= double, z= double
, vx= double, vy= double, vz= double
, mass= double
} // end of [planet]

typedef planetarr (n:int) = @[planet][n]

(* ****** ****** *)

infix 0 += -=  // for similar C notation
macdef += (x, d) = (,(x) := ,(x) + ,(d))
macdef -= (x, d) = (,(x) := ,(x) - ,(d))

fn advance {n:pos}
  (bodies: &planetarr n, n: int n, dt: double):<> void = () where {
  fun loop_inner
    {l1:addr} {n2:nat} {l2:addr} .<n2>. (
      pf1: !planet @ l1, pf2: !planetarr n2 @ l2
    | p1: ptr l1, p2: ptr l2, n2: int n2, dt: double
    ) :<> void =
    if n2 > 0 then let
      prval (pf21, pf22) = array_v_uncons {planet} (pf2)
      val dx = p1->x - p2->x and dy = p1->y - p2->y and dz = p1->z - p2->z
      val dist2 = dx * dx + dy * dy + dz * dz
      val dist = sqrt (dist2)
      val mag = dt / (dist * dist2)
//
      val mass = p2->mass
      val () = p1->vx -= dx * mass * mag
      val () = p1->vy -= dy * mass * mag
      val () = p1->vz -= dz * mass * mag
//
      val mass = p1->mass
      val () = p2->vx += dx * mass * mag
      val () = p2->vy += dy * mass * mag
      val () = p2->vz += dz * mass * mag
//
      val () = loop_inner (pf1, pf22 | p1, p2+sizeof<planet>, n2-1, dt)
      prval () = pf2 := array_v_cons {planet} (pf21, pf22)
    in
      // empty
    end // end of [if]
  // end of [loop_inner]
  fun loop_outer {n1:pos} {l1:addr} .<n1>. (
      pf1: !planetarr n1 @ l1 | p1: ptr l1, n1: int n1, dt: double
    ) :<> void =
    if n1 >= 2 then let
      prval (pf11, pf12) = array_v_uncons {planet} (pf1)
      val p2 = p1+sizeof<planet> and n2 = n1-1
      val () = loop_inner (pf11, pf12 | p1, p2, n2, dt)
      val () = loop_outer (pf12 | p2, n2, dt)
      prval () = pf1 := array_v_cons {planet} (pf11, pf12)
    in
      // empty
    end // end of [if]
  // end of [loop_outer]
  val () = loop_outer (view@ bodies | &bodies, n, dt)
  fun loop {n1:nat} {l1:addr} .<n1>. (
      pf1: !planetarr n1 @ l1 | p1: ptr l1, n1: int n1, dt: double
    ) :<> void =
    if n1 > 0 then let
      prval (pf11, pf12) = array_v_uncons {planet} (pf1)
      val () = p1->x += dt * p1->vx
      val () = p1->y += dt * p1->vy
      val () = p1->z += dt * p1->vz
      val () = loop (pf12 | p1+sizeof<planet>, n1-1, dt)
      prval () = pf1 := array_v_cons {planet} (pf11, pf12)
    in
      // empty
    end // end of [if]
  // end of [loop]
  val () = loop (view@ bodies | &bodies, n, dt)
} // end of [advance]

fn energy {n:pos}
  (bodies: &planetarr n, n: int n):<> double = e where {
  fun loop_inner
    {l1:addr} {n2:nat} {l2:addr} .<n2>. (
      pf1: !planet @ l1, pf2: !planetarr n2 @ l2
    | p1: ptr l1, p2: ptr l2, n2: int n2, e: &double
    ) :<> void =
    if n2 > 0 then let
      prval (pf21, pf22) = array_v_uncons {planet} (pf2)
      val dx = p1->x - p2->x
      and dy = p1->y - p2->y
      and dz = p1->z - p2->z
      val dist = sqrt (dx * dx + dy * dy + dz * dz)
      val () = e -= (p1->mass * p2->mass) / dist
      val () = loop_inner (pf1, pf22 | p1, p2+sizeof<planet>, n2-1, e)
      prval () = pf2 := array_v_cons {planet} (pf21, pf22)
    in
      // empty
    end // end of [if]
  // end of [loop_inner]
  fun loop_outer {n1:nat} {l1:addr} .<n1>. (
      pf1: !planetarr n1 @ l1 | p1: ptr l1, n1: int n1, e: &double
    ) :<> void =
    if n1 > 0 then let
      prval (pf11, pf12) = array_v_uncons {planet} (pf1)
      val vx = p1->vx and vy = p1->vy and vz = p1->vz
      val () = e += 0.5 * p1->mass * (vx * vx + vy * vy + vz * vz)
      val p2 = p1+sizeof<planet> and n2 = n1-1
      val () = loop_inner (pf11, pf12 | p1, p2, n2, e)
      val () = loop_outer (pf12 | p2, n2, e)
      prval () = pf1 := array_v_cons {planet} (pf11, pf12)
    in
      // empty
    end // end of [loop_outer]
  // end of [loop_outer]
  var e: double = 0.0
  val () = loop_outer (view@ bodies | &bodies, n, e)
} // end of [energy]

(* ****** ****** *)

#define PI 3.1415926535898
#define SOLAR_MASS (4.0 * PI * PI)

fn offmoment {n:pos}
  (bodies: &planetarr n, n: int n):<> void = () where {
  var px: double = 0.0 and py: double = 0.0 and pz: double = 0.0
  var i: natLte (n) // uninitialized
  val () = for* {i: nat | i <= n} .<n-i>. 
    (i: int i) => (i := 0; i < n; i := i + 1) let
    val mass = bodies.[i].mass
    val () = px += bodies.[i].vx * mass
    val () = py += bodies.[i].vy * mass
    val () = pz += bodies.[i].vz * mass
  in
    // empty
  end // end of [val]
  val () = bodies.[0].vx := ~ px / SOLAR_MASS
  val () = bodies.[0].vy := ~ py / SOLAR_MASS
  val () = bodies.[0].vz := ~ pz / SOLAR_MASS
} // end of [offset]

(* ****** ****** *)

#define N 5

sta l_theBodies: addr
extern prval pfbox_theBodies: vbox (planetarr(N) @ l_theBodies)
val p_theBodies = $extval (ptr (l_theBodies), "&theBodies[0]")

implement main (argc, argv) = () where {
  val () = assert (argc = 2)
  val n = int1_of (argv.[1]); val () = assert (n >= 2)
  prval vbox (pf_theBodies) = pfbox_theBodies
  val () = offmoment (!p_theBodies, N)
  val e_beg = energy (!p_theBodies, N)
  val () = $effmask_ref (printf ("%.9f\n", @(e_beg)))
  var i: int // unintialized ()
  val dt = 0.01
  val () = for (i := 0; i < n; i := i + 1) advance (!p_theBodies, N, dt)
  val e_fin = energy (!p_theBodies, N)
  val () = $effmask_ref (printf ("%.9f\n", @(e_fin)))
} // end of [main]

(* ****** ****** *)

// reuse some existing C code for initialization

%{^ // put at the beginning

#define PI 3.1415926535898
#define SOLAR_MASS (4.0 * PI * PI)
#define DAYS_PER_YEAR 365.24

#define NBODY 5

struct planet {
  double x; double y; double z; double vx; double vy; double vz; double mass;
} ;

struct planet theBodies[NBODY] = {
  { /* sun */
    0, 0, 0, 0, 0, 0, SOLAR_MASS
  }
, { /* jupiter */
    4.84143144246472090e+00,
   -1.16032004402742839e+00,
   -1.03622044471123109e-01,
    1.66007664274403694e-03 * DAYS_PER_YEAR,
    7.69901118419740425e-03 * DAYS_PER_YEAR,
   -6.90460016972063023e-05 * DAYS_PER_YEAR,
    9.54791938424326609e-04 * SOLAR_MASS
  }
, {  /* saturn */
    8.34336671824457987e+00,
    4.12479856412430479e+00,
   -4.03523417114321381e-01,
   -2.76742510726862411e-03 * DAYS_PER_YEAR,
    4.99852801234917238e-03 * DAYS_PER_YEAR,
    2.30417297573763929e-05 * DAYS_PER_YEAR,
    2.85885980666130812e-04 * SOLAR_MASS
  }
, { /* uranus */
    1.28943695621391310e+01,
   -1.51111514016986312e+01,
   -2.23307578892655734e-01,
    2.96460137564761618e-03 * DAYS_PER_YEAR,
    2.37847173959480950e-03 * DAYS_PER_YEAR,
   -2.96589568540237556e-05 * DAYS_PER_YEAR,
    4.36624404335156298e-05 * SOLAR_MASS
  }
, { /* neptune */
    1.53796971148509165e+01,
   -2.59193146099879641e+01,
    1.79258772950371181e-01,
    2.68067772490389322e-03 * DAYS_PER_YEAR,
    1.62824170038242295e-03 * DAYS_PER_YEAR,
   -9.51592254519715870e-05 * DAYS_PER_YEAR,
    5.15138902046611451e-05 * SOLAR_MASS
  }
} ;

%}

(* ****** ****** *)

(* end of [n-body2.dats] *)

 make, command-line, and program output logs

Wed, 23 Jan 2013 06:55:46 GMT

MAKE:
/usr/local/src/ats-lang-anairiats-0.2.9/bin/atscc  -pipe -Wall -O3 -fomit-frame-pointer -march=native -mfpmath=sse -msse3 nbody.dats -o nbody.ats-2.ats_run -lm
/usr/local/src/ats-lang-anairiats-0.2.9/bin/atsopt --output nbody_dats.c --dynamic nbody.dats
In file included from nbody_dats.c:19:0:
/usr/local/src/ats-lang-anairiats-0.2.9/prelude/CATS/basics.cats: In function ‘atspre_fprint_newline’:
/usr/local/src/ats-lang-anairiats-0.2.9/prelude/CATS/basics.cats:271:11: warning: variable ‘n2’ set but not used [-Wunused-but-set-variable]
/usr/local/src/ats-lang-anairiats-0.2.9/prelude/CATS/basics.cats:271:7: warning: variable ‘n1’ set but not used [-Wunused-but-set-variable]
nbody_dats.c: In function ‘advance_0’:
nbody_dats.c:375:1: warning: label ‘__ats_lab_advance_0’ defined but not used [-Wunused-label]
nbody_dats.c: In function ‘energy_4’:
nbody_dats.c:515:1: warning: label ‘__ats_lab_energy_4’ defined but not used [-Wunused-label]
nbody_dats.c: In function ‘offmoment_7’:
nbody_dats.c:590:1: warning: label ‘__ats_lab_1’ defined but not used [-Wunused-label]
nbody_dats.c:587:1: warning: label ‘__ats_lab_2’ defined but not used [-Wunused-label]
nbody_dats.c:560:1: warning: label ‘__ats_lab_offmoment_7’ defined but not used [-Wunused-label]
nbody_dats.c: In function ‘mainats’:
nbody_dats.c:653:1: warning: label ‘__ats_lab_4’ defined but not used [-Wunused-label]
nbody_dats.c:650:1: warning: label ‘__ats_lab_5’ defined but not used [-Wunused-label]
nbody_dats.c:632:1: warning: label ‘__ats_lab_mainats’ defined but not used [-Wunused-label]
In file included from nbody_dats.c:29:0:
nbody_dats.c: At top level:
/usr/local/src/ats-lang-anairiats-0.2.9/prelude/CATS/pointer.cats:52:14: warning: ‘atspre_null_ptr’ defined but not used [-Wunused-variable]
In file included from nbody_dats.c:30:0:
/usr/local/src/ats-lang-anairiats-0.2.9/prelude/CATS/printf.cats:57:1: warning: ‘atspre_fprintf_err’ defined but not used [-Wunused-function]
/usr/local/src/ats-lang-anairiats-0.2.9/prelude/CATS/printf.cats:69:1: warning: ‘atspre_fprintf_exn’ defined but not used [-Wunused-function]
/usr/local/src/ats-lang-anairiats-0.2.9/prelude/CATS/printf.cats:105:1: warning: ‘atspre_prerrf_exn’ defined but not used [-Wunused-function]
In file included from nbody_dats.c:33:0:
/usr/local/src/ats-lang-anairiats-0.2.9/prelude/CATS/string.cats:351:14: warning: ‘atspre_stropt_none’ defined but not used [-Wunused-variable]
gcc -I/usr/local/src/ats-lang-anairiats-0.2.9/ -I/usr/local/src/ats-lang-anairiats-0.2.9/ccomp/runtime/ -L/usr/local/src/ats-lang-anairiats-0.2.9/ccomp/lib/ /usr/local/src/ats-lang-anairiats-0.2.9/ccomp/runtime/ats_prelude.c -pipe -Wall -O3 -fomit-frame-pointer -march=native -mfpmath=sse -msse3 nbody_dats.c -o nbody.ats-2.ats_run -lm -lats 
0.37s to complete and log all make actions

COMMAND LINE:
./nbody.ats-2.ats_run 50000000

PROGRAM OUTPUT:
-0.169075164
-0.169059907

Revised BSD license

  Home   Conclusions   License   Play