
-- PERFORMANCE MEASUREMENT : Measure the time to do an unchecked
--                           conversion of an array of 10 floating components
--                           into a record of 10 floating components.

with Unchecked_Conversion;
with Remote_Global;
use Remote_Global; -- control optimization
with Iteration; -- obtain stable measurement
with Piwg_Io; -- output results

procedure H000006 is  -- main procedure to execute

    Cpu_Time : Duration; -- CPU time for one feature execution
    Wall_Time : Duration; -- WALL time for one feature execution
    Check_Times : constant := 100; -- inside loop count and check
    Iteration_Count : Integer; -- set and varied by ITERATION package
    Stable : Boolean; -- true when measurement stable

    type Float_Array is array (0 .. 9) of Float;
    type Float_Record is
        record
            F0, F1, F2, F3, F4, F5, F6, F7, F8, F9 : Float;
        end record;
    function Move is new Unchecked_Conversion (Float_Array, Float_Record);
    F_A : Float_Array;
    F_R : Float_Record;

begin

    Iteration.Start_Control;  -- dummy to bring in pages on some machines

    delay 0.5;  -- wait for stable enviornment on some machines

    Iteration.Initialize (Iteration_Count);

    loop  -- until stable measurement, ITERATION_COUNT increases each time

--
-- Control loop
--
        Iteration.Start_Control;
        for J in 1 .. Iteration_Count loop
            Global := 0;
            for Inside_Loop in 1 .. Check_Times loop
                Global := Global + A_One; -- prevent optimization
                Remote;
                F_A (A_One) := Float (Global);
                F_R.F1 := F_A (A_One);
                if F_A (1) /= F_R.F1 then
                    raise Program_Error; -- incorrect code
                end if;
            end loop;
        end loop;
        Iteration.Stop_Control (Global, Check_Times);

--
-- Test loop
--
        Iteration.Start_Test;
        for J in 1 .. Iteration_Count loop
            Global := 0;
            for Inside_Loop in 1 .. Check_Times loop
                Global := Global + A_One; -- prevent optimization
                Remote;
                F_A (A_One) := Float (Global);
                F_R := Move (F_A);
                if F_A (1) /= F_R.F1 then -- check for correct code
                    raise Program_Error; -- incorrect code
                end if;
            end loop;
        end loop;
        Iteration.Stop_Test (Global, Check_Times);
        Iteration.Test_Stable (Iteration_Count, Stable);
        exit when Stable;
    end loop;
--
    Iteration.Feature_Times (Cpu_Time, Wall_Time);

--
-- Printout
--
    Piwg_Io.Piwg_Output
       ("H000006", "Chapter 13", Cpu_Time, Wall_Time, Iteration_Count,
        " The time for UNCHECKED_CONVERSION to move 10 floating array",
        " objects to a 10 component floating record", " ");

end H000006;