Re: GNAT compiler switches and optimization



On Sun, 2006-10-22 at 14:24 -0400, Jeffrey Creem wrote:

It sounds like you are running some different code and I'd be hestitant
to make any assertions about runtime for certain constructs without
seeing it since

It is appended below.

2) You mention something about just accessing first, middle and last of
your arrays so it really sounds like you really are just timing
allocations and and not actually really hitting the array indexing
(though hard to say without seeing the code).

Yes, I had concentrated on just this question, asked by Thomas Krauss,
about stack versus heap allocation. If a program is not frequently
allocating and freeing arrays (or matrices, etc.), the the effects
might be less of an issue, if they are an issue at all when there
is no initialization.
But I imagined allocation is just what is happening all the time
if you have a function that computes matrices of varying sizes?
OTOH, I find very different results on GNU/Linux (for which I only
have a number of GNATs). Stack allocation appears to be consuming
next to no time. (Commit on write? Just remembering an offset?)

Below the following program, there is a patch that adds trivial
initialization loops. With them, a comparison of stack vs heap
on GNU/Linux seems in favor of the stack. I can't check this on
Windows right now, though.

with Ada.Calendar;
with Ada.Text_IO;
with Ada.Unchecked_Deallocation;

procedure main is
use Ada.Calendar, Ada;

type LIST is array (NATURAL range <>) of BOOLEAN;
for LIST'component_size use 8;
-- for a "normal" array, not packed or other magic

type LIST_PTR is access LIST;
procedure free is new Ada.Unchecked_Deallocation
(LIST, LIST_PTR);

accu: BOOLEAN := false;
-- The allocating functions read and write this variable
-- using components of the local arrays.
-- (This should prevent some optimizations.)

function allocate(size: POSITIVE) return BOOLEAN;
-- use a local `LIST` of length `size`

function allocate_heap(size: POSITIVE) return BOOLEAN;
-- use a pointer to a new `LIST` of length `size`

function image(t: TIME) return STRING;
-- the current time as a `STRING` value


function allocate(size: POSITIVE) return BOOLEAN is
done: LIST(1 .. size); -- pragma volatile(done);
result: BOOLEAN;
begin
if done(size / 2) then
result := false;
end if;
done(done'last) := accu and done(done'first);
result := done(done'last) and done(done'first);
return result;
end allocate;

function allocate_heap(size: POSITIVE) return BOOLEAN is
done: LIST_PTR;
result: BOOLEAN;
begin
done := new LIST(1 .. size);
if done(size / 2) then
result := false;
end if;
done(done'last) := accu and done(done'first);
result := done(done'first) and done(done'first);
Free(done);
return result;
end allocate_heap;

function image(t: TIME) return STRING is
year: YEAR_NUMBER;
day: DAY_NUMBER;
month: MONTH_NUMBER;
sec: DURATION;
begin
split(t, year, month, day, sec);
return YEAR_NUMBER'image(year)
& MONTH_NUMBER'image(month)
& DAY_NUMBER'image(day)
& DURATION'image(sec);
end image;


start, finish: TIME;


begin
Text_IO.put_line("using a stack");
start := clock;
for run in 1 .. 25 loop
for k in 1 .. 2000 loop
accu := allocate(5000 * k);
end loop;
end loop;
finish := clock;

Text_IO.put_line("from" & image(start)
& " to" & image(finish)
& " = " & DURATION'image(finish - start));
Text_IO.put_line("accu " & BOOLEAN'image(accu));


Text_IO.put_line("using a heap");
start := clock;
for run in 1 .. 25 loop
for k in 1 .. 2000 loop
accu := allocate_heap(5000 * k);
end loop;
end loop;
finish := clock;

Text_IO.put_line("from" & image(start)
& " to" & image(finish)
& " = " & DURATION'image(finish - start));
Text_IO.put_line("accu " & BOOLEAN'image(accu));
end main;



--- stack_use_testing.ada 2006/10/22 23:51:48 1.1
+++ stack_use_testing.ada 2006/10/22 23:52:12
@@ -33,2 +33,3 @@
begin
+ for k in done'range loop done(k) := false; end loop;
if done(size / 2) then
@@ -46,2 +47,3 @@
done := new LIST(1 .. size);
+ for k in done'range loop done(k) := false; end loop;
if done(size / 2) then
@@ -75,4 +77,4 @@
start := clock;
- for run in 1 .. 25 loop
- for k in 1 .. 2000 loop
+ for run in 1 .. 2 loop
+ for k in 1 .. 200 loop
accu := allocate(5000 * k);
@@ -90,4 +92,4 @@
start := clock;
- for run in 1 .. 25 loop
- for k in 1 .. 2000 loop
+ for run in 1 .. 2 loop
+ for k in 1 .. 200 loop
accu := allocate_heap(5000 * k);


.



Relevant Pages

  • Re: Whats the best language to learn...
    ... over the arrays of vertices, ... loop over the selected models; ... recently my edge construction and shadow-volume rendering code ... but enums just make it easier and quicker to make ...
    (comp.programming)
  • Re: MKDir not working
    ... Public Sub MkDirs ... first argument of the Split function in the active loop statement; ... track and return a Boolean status from the function. ... MkDirs = MkDirs + Err.Number ...
    (microsoft.public.vb.general.discussion)
  • Re: Non-rectangular 3D plot
    ... Ok I see where my code would get very confusing now. ... I originally had it accepting arrays for my inputs, ... I have shown my new code below without x and y in the for loop. ... to have y increment over a counter j for a given x value. ...
    (comp.soft-sys.matlab)
  • HHow can we Speed Up This Wend/While Loop
    ... I need some assistance to speed up a while / wend loop which I have ... The purpose of the loop is to populate two single dimension ... The recordset is made up of two columns, ... The two arrays on the other hand are called strLabel and curData, ...
    (comp.lang.basic.visual.misc)
  • RE: Fastest Selection
    ... Just loop through the arrays until a match is found and use the key's index ... Both are very fast but the Instr method typically is 20% faster. ... Dim sStr as String ...
    (microsoft.public.vb.general.discussion)