From: Guillaume Foliard <guifo@wanadoo.fr>
Subject: Re: Benchmark Ada, please
Date: Sat, 05 Jul 2014 14:34:39 +0200
Date: 2014-07-05T14:34:39+02:00 [thread overview]
Message-ID: <lp8rct$f4a$1@speranza.aioe.org> (raw)
In-Reply-To: lp6nva$q8g$1@speranza.aioe.org
Victor Porton wrote:
> Somebody, write an Ada benchmark for this comparison of programming
> languages:
>
> https://github.com/jesusfv/Comparison-Programming-Languages-Economics
Here is it:
---------------------------------------------------------------------
with Ada.Execution_Time;
with Ada.Numerics.Long_Elementary_Functions;
with Ada.Real_Time;
with Ada.Text_IO;
use Ada.Numerics.Long_Elementary_Functions;
use type Ada.Execution_Time.CPU_Time;
procedure Rbc_Ada
is
Grid_Capital_Length : constant := 17820;
Grid_Productivity_Length : constant := 5;
type Grid_Capital_Index is
new Integer range 0 .. Grid_Capital_Length - 1;
type Grid_Productivity_Index is
new Integer range 0 .. Grid_Productivity_Length - 1;
type Grid_Array_Type is
array (Grid_Capital_Index, Grid_Productivity_Index)
of Long_Float;
Null_Grid : constant Grid_Array_Type := (others => (others => 0.0));
-- 1. Calibration
-- Elasticity of output w.r.t. capital
Alpha : constant Long_Float := 0.33333333333;
-- Discount factor
Beta : constant Long_Float := 0.95;
-- Productivity values
Productivities : constant
array (Grid_Productivity_Index)
of Long_Float :=
(0.9792, 0.9896, 1.0000, 1.0106, 1.0212);
-- Transition matrix
Transition : constant
array (Grid_Productivity_Index, Grid_Productivity_Index)
of Long_Float :=
((0.9727, 0.0273, 0.0000, 0.0000, 0.0000),
(0.0041, 0.9806, 0.0153, 0.0000, 0.0000),
(0.0000, 0.0082, 0.9837, 0.0082, 0.0000),
(0.0000, 0.0000, 0.0153, 0.9806, 0.0041),
(0.0000, 0.0000, 0.0000, 0.0273, 0.9727));
-- 2. Steady State
Capital_Steady_State : constant Long_Float :=
(Alpha * Beta) ** (1.0 / (1.0 - Alpha));
Output_Steady_State : constant Long_Float :=
Capital_Steady_State ** Alpha;
Consumption_Steady_State : constant Long_Float :=
Output_Steady_State - Capital_Steady_State;
Grid_Capital_Next_Index : Grid_Capital_Index;
Grid_Capital : array (Grid_Capital_Index) of Long_Float :=
(others => 0.0);
Output : Grid_Array_Type := Null_Grid;
Value_Function : Grid_Array_Type := Null_Grid;
Value_Function_New : Grid_Array_Type := Null_Grid;
Policy_Function : Grid_Array_Type := Null_Grid;
Expected_Value_Function : Grid_Array_Type := Null_Grid;
Max_Difference : Long_Float := 10.0;
Diff : Long_Float;
Diff_High_So_Far : Long_Float;
Tolerance : constant := 0.0000001;
Value_High_So_Far : Long_Float;
Value_Provisional : Long_Float;
Consumption : Long_Float;
Capital_Choice : Long_Float;
Iteration : Integer := 0;
Cpu_Time_Start : Ada.Execution_Time.CPU_Time;
Cpu_Time_End : Ada.Execution_Time.CPU_Time;
begin
Cpu_Time_Start := Ada.Execution_Time.Clock;
Ada.Text_IO.Put_Line
("Output =" & Output_Steady_State'Img
& ", Capital =" & Capital_Steady_State'Img
& ", Consumption =" & Consumption_Steady_State'Img);
-- We generate the grid of capital
for Index in Grid_Capital'Range
loop
Grid_Capital (Index) :=
0.5 * Capital_Steady_State + 0.00001 * Long_Float (Index);
end loop;
-- We pre-build output for each point in the grid
for Productivity_Index in Grid_Productivity_Index
loop
for Capital_Index in Grid_Capital_Index
loop
Output (Capital_Index, Productivity_Index) :=
Productivities (Productivity_Index)
* Grid_Capital (Capital_Index) ** Alpha;
end loop;
end loop;
-- Main iteration
while Max_Difference > Tolerance
loop
for Productivity_Index in Grid_Productivity_Index
loop
for Capital_Index in Grid_Capital_Index
loop
Expected_Value_Function (Capital_Index, Productivity_Index) :=
0.0;
for Productivity_Next_Index in Grid_Productivity_Index
loop
Expected_Value_Function (Capital_Index, Productivity_Index)
:=
Expected_Value_Function (Capital_Index,
Productivity_Index)
+ Transition (Productivity_Index, Productivity_Next_Index)
* Value_Function (Capital_Index, Productivity_Next_Index);
end loop;
end loop;
end loop;
for Productivity_Index in Grid_Productivity_Index
loop
-- We start from previous choice (monotonicity of policy function)
Grid_Capital_Next_Index := 0;
for Capital_Index in Grid_Capital_Index
loop
Value_High_So_Far := -100000.0;
Capital_Choice := Grid_Capital (0);
for Capital_Next_Index in
Grid_Capital_Next_Index .. Grid_Capital_Index'Last
loop
Consumption :=
Output (Capital_Index, Productivity_Index)
- Grid_Capital (Capital_Next_Index);
Value_Provisional :=
(1.0 - Beta) * Log (Consumption)
+ Beta * Expected_Value_Function (Capital_Next_Index,
Productivity_Index);
if Value_Provisional > Value_High_So_Far
then
Value_High_So_Far := Value_Provisional;
Capital_Choice := Grid_Capital (Capital_Next_Index);
Grid_Capital_Next_Index := Capital_Next_Index;
else
exit;
end if;
Value_Function_New (Capital_Index, Productivity_Index) :=
Value_High_So_Far;
Policy_Function (Capital_Index, Productivity_Index) :=
Capital_Choice;
end loop;
end loop;
end loop;
Diff_High_So_Far := -100000.0;
for Productivity_Index in Grid_Productivity_Index
loop
for Capital_Index in Grid_Capital_Index
loop
Diff :=
abs (Value_Function (Capital_Index, Productivity_Index)
- Value_Function_New (Capital_Index,
Productivity_Index));
if Diff > Diff_High_So_Far
then
Diff_High_So_Far := Diff;
end if;
Value_Function (Capital_Index, Productivity_Index)
:= Value_Function_New (Capital_Index, Productivity_Index);
end loop;
end loop;
Max_Difference := Diff_High_So_Far;
Iteration := Iteration + 1;
if Iteration mod 10 = 0 or Iteration = 1
then
Ada.Text_IO.Put_Line ("Iteration =" & Iteration'Img
& ", Sup Diff =" & Max_Difference'Img);
end if;
end loop;
Ada.Text_IO.Put_Line ("Iteration =" & Iteration'Img
& ", Sup Diff =" & Max_Difference'Img);
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line ("My check =" & Policy_Function (999, 2)'Img);
Ada.Text_IO.New_Line;
Cpu_Time_End := Ada.Execution_Time.Clock;
Ada.Text_IO.Put_Line
("Elapsed time is ="
& Ada.Real_Time.To_Duration (Cpu_Time_End - Cpu_Time_Start)'Img);
end Rbc_Ada;
---------------------------------------------------------------------
This is mostly a line to line translation from RBC_CPP.cpp. I have
added a few type declarations though.
> It seems that C++ was the fastest (faster than Fortran), but Ada may be
> even faster.
Here are the numbers with GNAT GPL 2014 on a Core2 Q9650 @ 3.00GHz:
$ gnatmake -O3 rbc_ada.adb
$ time ./rbc_ada
...
Elapsed time is = 1.966112682
As for the C++ version:
$ g++ -o testc -O3 RBC_CPP.cpp
$ time ./testc
...
Elapsed time is = 3.12033
So the Ada version is significantly faster. I suppose it is mainly because
the Ada compiler has vectorized more loops than the C++ compiler (add -
ftree-vectorizer-verbose=2 to the above compilation commands to check by
yourself).
> If we succeed, we would advertise Ada as the fastest(!) programming
> language (after assembler).
Feel free to advertise, using this Ada code as you wish.
--
Guillaume Foliard
next prev parent reply other threads:[~2014-07-05 12:34 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-04 17:23 Benchmark Ada, please Victor Porton
2014-07-05 12:34 ` Guillaume Foliard [this message]
2014-07-05 13:00 ` Niklas Holsti
2014-07-05 17:00 ` Guillaume Foliard
2014-07-05 18:29 ` Niklas Holsti
2014-07-05 18:44 ` Niklas Holsti
2014-07-05 18:50 ` Guillaume Foliard
2014-07-05 19:09 ` Niklas Holsti
2014-07-05 16:33 ` Simon Wright
2014-07-05 18:25 ` Guillaume Foliard
2014-07-06 17:24 ` Dirk Heinrichs
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox