From: tmoran@acm.org
Subject: Re: Gnat 3.15p & Windows & Hyperthreading Q
Date: Sat, 26 Mar 2005 12:36:20 -0600
Date: 2005-03-26T12:36:20-06:00 [thread overview]
Message-ID: <DPadnZq_15c5NtjfRVn-oQ@comcast.com> (raw)
In-Reply-To: rPd1e.9183$S46.1228@newsread3.news.atl.earthlink.net
> > I'm told that a multitask program compiled with Gnat 3.15p and run
> > under Windows XP Pro on a hyperthreaded machine, runs in the same total
> > time as the same program using a single task. OTOH, when compiled with
> > GNAT 5.02a1 and run on a dual-processor 400 MHz Celeron running Mandrake
> > Linux 8.2, it runs about 50% faster with two rather than one tasks.
>
> That seems strange. In the first case, is it a SINGLE processor machine?
> Or is it the same dual processor 400mhz Celeron in both cases?
> Also, is this just anecdotal or is there an actual benchmark program
> that could be looked at?
The original program was posted under "Ada bench : count words",
as was the dual-Celeron timing. The hyperthreading timing was a personal
communication. It's possible the person was mistaken in thinking they
had hyperthreading turned on, with processor affinities set correctly.
I'm inquiring further.
So here's the benchmark. It reads a text file from Standard Input,
preferably at least a megabyte to get a decent timing read, and prints
line, word, and character counts to Standard Output. The number of
CPU-heavy tasks is the number of elements of
Counter : array(1 .. 2) of Counters;
Probably increasing the buffer size, by lessening task interactions,
would speed it up and improve the multi-tasking benefit.
with Ada.Calendar,
Ada.Streams,
Ada.Streams.Stream_IO,
Ada.Text_IO,
Ada.Text_IO.Text_Streams;
procedure Cwt is
use Ada.Streams;
use type Ada.Calendar.Time;
T0 : Ada.Calendar.Time := Ada.Calendar.Clock; -- start timing
T1 : Ada.Calendar.Time;
subtype Buffer_Type is Stream_Element_Array(1 .. 4096);
LF : constant Stream_Element := Character'pos(Ascii.LF);
Is_Whitespace : constant array(Stream_Element) of Boolean
:= (Character'pos(Ascii.LF) | Character'pos(Ascii.HT)
| Character'pos(' ') => True, others => False);
-- "Counters" tasks run independently, asking Data_Source for buffer loads
-- and tallying word and line counts. When done, they wait for their
-- (partial) counts to be harvested, then terminate.
task type Counters is
entry Harvest(Line_Count, Word_Count : out Natural);
end Counters;
-- Data_Source is the IO task, supplying data as requested to Counters.
-- Note that Data_Source counts the whitespace->non-white transitions
-- at the ends of buffers. Counters' partial counts are added to that.
-- Data_Source also counts the Total number of characters.
task Data_Source is
entry Get(Buffer : out Buffer_Type;
Last : out Stream_Element_Offset);
end Data_Source;
task body Counters is
Buffer : Buffer_Type;
Last : Stream_Element_Offset;
Lines, Words, Total : Natural := 0;
In_Whitespace : Boolean;
begin
loop
Data_Source.Get(Buffer, Last);
exit when Last = 0;
In_Whitespace := Is_Whitespace(Buffer(1));
for I in 1 .. Last loop
if Is_Whitespace(Buffer(I)) then
if Buffer(I) = LF then
Lines := Lines + 1;
end if;
In_Whitespace := True;
elsif In_Whitespace then
In_Whitespace := False;
Words := Words + 1;
end if;
end loop;
exit when Last < Buffer'last;
end loop;
accept Harvest(Line_Count, Word_Count : out Natural) do
Line_Count := Lines;
Word_Count := Words;
end;
end Counters;
Lines, Words, Total : Natural := 0;
task body Data_Source is
Stream : Ada.Text_IO.Text_Streams.Stream_Access;
At_End : Boolean := False;
In_Whitespace : Boolean := True; -- we must count at edges of buffer loads
begin
Stream := Ada.Text_IO.Text_Streams.Stream(Ada.Text_IO.Current_Input);
loop
select
accept Get(Buffer : out Buffer_Type;
Last : out Stream_Element_Offset) do
if At_End then Last := 0;
else
Ada.Streams.Read(Ada.Streams.Root_Stream_Type'Class(Stream.all),
Buffer, Last);
Total := Total+Integer(Last);
if Last > 0 then
if In_Whitespace and not Is_Whitespace(Buffer(1)) then
Words := Words+1;
end if;
In_Whitespace := Is_Whitespace(Buffer(Last));
end if;
if Last < Buffer'last then At_End := True;end if;
end if;
end;
or terminate;
end select;
end loop;
end Data_Source;
A_Line_Count, A_Word_Count : Natural := 0;
Counter : array(1 .. 2) of Counters;
begin
for i in Counter'range loop
Counter(i).Harvest(A_Line_Count, A_Word_Count);
Lines := Lines+A_Line_Count;
Words := Words+A_Word_Count;
end loop;
T1 := Ada.Calendar.Clock;
Ada.Text_IO.Put_Line(Natural'Image(Lines)
& Natural'Image(Words)
& Natural'Image(Total));
Ada.Text_IO.Put_Line("took" & Duration'Image(T1 - T0));
end Cwt;
next prev parent reply other threads:[~2005-03-26 18:36 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-03-26 0:28 Gnat 3.15p & Windows & Hyperthreading Q tmoran
2005-03-26 4:45 ` Steve
2005-03-26 9:41 ` Pascal Obry
2005-03-26 13:53 ` Marin David Condic
2005-03-26 18:36 ` tmoran [this message]
2005-03-28 13:16 ` Marin David Condic
2005-03-27 11:27 ` Simon Wright
2005-03-29 18:33 ` Wiljan Derks
2005-03-30 8:48 ` Adrien Plisson
2005-04-01 7:09 ` tmoran
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox