performance measurements

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

 N  CPU secs Elapsed secs Memory KB Code B ≈ CPU Load

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

GNATMAKE 4.6

gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)

 n-body Ada 2005 GNAT #2 program source code

--
-- The Computer Language Benchmarks Game
-- http://benchmarksgame.alioth.debian.org/
-- 
-- Contributed by Pascal Obry (2005/03/21)
-- Modified by Jonathan Parker 
--
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Text_IO;      use Ada.Text_IO;
with Nbody_Pck;        use Nbody_Pck;

procedure Nbody is

   N : constant Integer := Integer'Value (Argument (1));

   Bodies : Planets :=
     (Sun     => 
        (X    => 0.0,
         Y    => 0.0,
         Z    => 0.0,
         Vx   => 0.0,
         Vy   => 0.0,
         Vz   => 0.0,
         Mass => Solar_Mass),
      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),
      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),
      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),
      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));

   package RIO is new Float_IO (Real);

   procedure Put
     (Item : in Real; 
      Fore : in Field := 0; 
      Aft  : in Field := 9;
      Exp  : in Field := 0) 
   renames RIO.Put;

   Px, Py, Pz : Real := 0.0;

begin

   for I in Bodies'Range loop
      Px := Px + Bodies (I).Vx * Bodies (I).Mass;
      Py := Py + Bodies (I).Vy * Bodies (I).Mass;
      Pz := Pz + Bodies (I).Vz * Bodies (I).Mass;
   end loop;

   Offset_Momentum (Bodies (Sun), Px, Py, Pz);

   Put (Energy (Bodies));
   New_Line;

   for K in 1 .. N loop
      Advance (Bodies, 0.01);
   end loop;

   Put (Energy (Bodies));
   New_Line;

 --testing:
 --for I in Body_id loop
 --  put(Bodies(I).X); put(" "); 
 --end loop;

end Nbody;

with Ada.Numerics; use Ada.Numerics;
with Ada.Numerics.Generic_Elementary_Functions;

package Nbody_Pck is

   type Real is digits 15;

   package Math is new Ada.Numerics.Generic_Elementary_Functions (Real);

   Solar_Mass    : constant Real := 4.0 * Pi * Pi;
   Days_Per_Year : constant Real := 365.24;

   type Data is
      record
         X, Y, Z : Real;
         Vx, Vy, Vz : Real;
         Mass : Real;
      end record;

   type Uns is mod 2**64;

   subtype Body_id is Uns range 0 .. 4;

   Sun     : constant := Body_id'First + 0;
   Jupiter : constant := Body_id'First + 1;
   Saturn  : constant := Body_id'First + 2;
   Neptune : constant := Body_id'First + 3;
   Uranus  : constant := Body_id'First + 4;

   type Planets is array (Body_id) of Data;

   procedure Offset_Momentum
     (Planet     : in out Data;
      Px, Py, Pz : in     Real);

   function Energy (Bodies : in Planets) return Real;

   procedure Advance (Bodies : in out Planets; Dt : in Real);

end Nbody_Pck;

package body Nbody_Pck is

   procedure Offset_Momentum
     (Planet     : in out Data;
      Px, Py, Pz : in     Real) is
   begin
      Planet.Vx := -Px / Solar_Mass;
      Planet.Vy := -Py / Solar_Mass;
      Planet.Vz := -Pz / Solar_Mass;
   end Offset_Momentum;

   function Energy (Bodies : in Planets) return Real is
      Dx, Dy, Dz, Distance : Real;
      E                    : Real := 0.0;
   begin
      for I in Bodies'Range loop
         E := E + 0.5 * Bodies (I).Mass
              * (Bodies (I).Vx * Bodies (I).Vx
               + Bodies (I).Vy * Bodies (I).Vy
               + Bodies (I).Vz * Bodies (I).Vz);

         for J in Bodies'Range loop
            if J > I then
               Dx := Bodies (I).X - Bodies (J).X;
               Dy := Bodies (I).Y - Bodies (J).Y;
               Dz := Bodies (I).Z - Bodies (J).Z;
               Distance := Math.Sqrt (Dx * Dx + Dy * Dy + Dz * Dz);
               E := E - (Bodies (I).Mass * Bodies (J).Mass) / Distance;
            end if;
         end loop;
      end loop;
      return E;
   end Energy;

   procedure Advance (Bodies : in out Planets; Dt : in Real) is
      Dx, Dy, Dz, Mag : Real;
      Delta_r_sqr : Real;
   begin
      for I in Bodies'Range loop
         for J in Bodies'Range loop
            if J < I then
               Dx := (Bodies (I).X - Bodies (J).X);
               Dy := (Bodies (I).Y - Bodies (J).Y);
               Dz := (Bodies (I).Z - Bodies (J).Z);

               Delta_r_sqr := Dx*Dx + Dy*Dy + Dz*Dz;
               Mag         := Dt / (Delta_r_sqr * Math.Sqrt (Delta_r_sqr));

               Bodies (I).Vx := Bodies (I).Vx - Dx  * Bodies (J).Mass * Mag;
               Bodies (I).Vy := Bodies (I).Vy - Dy  * Bodies (J).Mass * Mag;
               Bodies (I).Vz := Bodies (I).Vz - Dz  * Bodies (J).Mass * Mag;
               Bodies (J).Vx := Bodies (J).Vx + Mag * Bodies (I).Mass * Dx;
               Bodies (J).Vy := Bodies (J).Vy + Mag * Bodies (I).Mass * Dy;
               Bodies (J).Vz := Bodies (J).Vz + Mag * Bodies (I).Mass * Dz;
            end if;
         end loop;
      end loop;

      for I in Bodies'Range loop
         Bodies (I).X := Bodies (I).X + Dt * Bodies (I).Vx;
         Bodies (I).Y := Bodies (I).Y + Dt * Bodies (I).Vy;
         Bodies (I).Z := Bodies (I).Z + Dt * Bodies (I).Vz;
      end loop;
   end Advance;

end Nbody_Pck;

 make, command-line, and program output logs

Sat, 19 Jan 2013 07:57:51 GMT

MAKE:
/usr/bin/gnatchop -r -w nbody.gnat-2.gnat
splitting nbody.gnat-2.gnat into:
   nbody.adb
   nbody_pck.ads
   nbody_pck.adb
/usr/bin/gnatmake -O3 -fomit-frame-pointer -march=native -msse3 -mfpmath=sse -gnatNp -f nbody.adb -o nbody.gnat-2.gnat_run 
gcc-4.6 -c -O3 -fomit-frame-pointer -march=native -msse3 -mfpmath=sse -gnatNp nbody.adb
gcc-4.6 -c -O3 -fomit-frame-pointer -march=native -msse3 -mfpmath=sse -gnatNp nbody_pck.adb
gnatbind -x nbody.ali
gnatlink nbody.ali -O3 -fomit-frame-pointer -march=native -msse3 -mfpmath=sse -o nbody.gnat-2.gnat_run
0.95s to complete and log all make actions

COMMAND LINE:
./nbody.gnat-2.gnat_run 50000000

PROGRAM OUTPUT:
-0.169075164
-0.169059907

Revised BSD license

  Home   Conclusions   License   Play