* Gnat 3.15p & Windows & Hyperthreading Q
@ 2005-03-26 0:28 tmoran
2005-03-26 4:45 ` Steve
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: tmoran @ 2005-03-26 0:28 UTC (permalink / raw)
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.
Is the problem "hyperthreading", Windows, or Gnat 3.15p?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Gnat 3.15p & Windows & Hyperthreading Q
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
` (2 subsequent siblings)
3 siblings, 0 replies; 10+ messages in thread
From: Steve @ 2005-03-26 4:45 UTC (permalink / raw)
Another data point, but not one you asked for...
I have seen Gnat 3.15p take advantage of dual Xeons on a W2k machine. So I
don't think there is anything wrong in general with Gnat 3.15p on dual
processors.
Steve
(The Duck)
<tmoran@acm.org> wrote in message news:1IOdnWpX0_s6MdnfRVn-3A@comcast.com...
> 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.
> Is the problem "hyperthreading", Windows, or Gnat 3.15p?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Gnat 3.15p & Windows & Hyperthreading Q
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-29 18:33 ` Wiljan Derks
3 siblings, 0 replies; 10+ messages in thread
From: Pascal Obry @ 2005-03-26 9:41 UTC (permalink / raw)
tmoran@acm.org writes:
> 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
I don't think it is true. GNAT maps tasks to OS threads, so it could be
a problem with the Windows XP used on the dual processor. Some WinXP
(could be the case for the Home Edition) does not support multiproc.
Pascal.
--
--|------------------------------------------------------
--| Pascal Obry Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--| http://www.obry.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Gnat 3.15p & Windows & Hyperthreading Q
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
2005-03-27 11:27 ` Simon Wright
2005-03-29 18:33 ` Wiljan Derks
3 siblings, 2 replies; 10+ messages in thread
From: Marin David Condic @ 2005-03-26 13:53 UTC (permalink / raw)
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? Depending
on what exactly is in the tasks in question, it would be hard to imagine
not seeing some improvement going multitasking with multiprocessors.
(Task overhead shouldn't be THAT bad.) When dealing with the underlying
OS, there might be lots of possible problems that might lock the process
to a single processor & account for the lack of improvement.
Also, is this just anecdotal or is there an actual benchmark program
that could be looked at?
MDC
tmoran@acm.org wrote:
> 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.
> Is the problem "hyperthreading", Windows, or Gnat 3.15p?
--
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/NSFrames.htm
Send Replies To: m o d c @ a m o g
c n i c . r
"'Shut up,' he explained."
-- Ring Lardner
======================================================================
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Gnat 3.15p & Windows & Hyperthreading Q
2005-03-26 13:53 ` Marin David Condic
@ 2005-03-26 18:36 ` tmoran
2005-03-28 13:16 ` Marin David Condic
2005-03-27 11:27 ` Simon Wright
1 sibling, 1 reply; 10+ messages in thread
From: tmoran @ 2005-03-26 18:36 UTC (permalink / raw)
> > 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;
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Gnat 3.15p & Windows & Hyperthreading Q
2005-03-26 13:53 ` Marin David Condic
2005-03-26 18:36 ` tmoran
@ 2005-03-27 11:27 ` Simon Wright
1 sibling, 0 replies; 10+ messages in thread
From: Simon Wright @ 2005-03-27 11:27 UTC (permalink / raw)
Marin David Condic <nobody@noplace.com> writes:
> 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?
It's my dual-processor Celeron, and it doesn't run Windows.
--
Simon Wright 100% Ada, no bugs.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Gnat 3.15p & Windows & Hyperthreading Q
2005-03-26 18:36 ` tmoran
@ 2005-03-28 13:16 ` Marin David Condic
0 siblings, 0 replies; 10+ messages in thread
From: Marin David Condic @ 2005-03-28 13:16 UTC (permalink / raw)
On a quick scan, I don't see anything obvious. Let me take a look at it
and I'll see if I spot anything that might be problematic.
MDC
tmoran@acm.org wrote:
>
> 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;
--
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/NSFrames.htm
Send Replies To: m o d c @ a m o g
c n i c . r
"'Shut up,' he explained."
-- Ring Lardner
======================================================================
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Gnat 3.15p & Windows & Hyperthreading Q
2005-03-26 0:28 Gnat 3.15p & Windows & Hyperthreading Q tmoran
` (2 preceding siblings ...)
2005-03-26 13:53 ` Marin David Condic
@ 2005-03-29 18:33 ` Wiljan Derks
2005-03-30 8:48 ` Adrien Plisson
3 siblings, 1 reply; 10+ messages in thread
From: Wiljan Derks @ 2005-03-29 18:33 UTC (permalink / raw)
I did some performance tests on XP profesional with hyperthreading on a
2.8Ghz P4.
For that I used some code that checks the CPU performance.
I did this by making some compute procedure and check how often it is
calculated.
In my program I did make multiple tasks to check the functioning of hyper
threaded.
It turns out that hyper threading does not help at all with the total
perfromance that is available.
My conclusions where as follows:
* When hyperthreading is turned of, the system can do X computations.
* When hyperthreading is turned on and both threads are loaded, each of
them can typically do less then X/2 computations.
Thus turning on hyper threading gives basically two CPU which are both half
speed when being used.
When one of the CPU's is free, the other is faster.
So it looks like one CPU is multiplexed in time (but very fast).
The only advantage that hyper threading has, is that the system might be
more responsive.
Thus when accidentally locking one CPU at high priority, one can still break
into the system (using the other CPU).
Wiljan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Gnat 3.15p & Windows & Hyperthreading Q
2005-03-29 18:33 ` Wiljan Derks
@ 2005-03-30 8:48 ` Adrien Plisson
2005-04-01 7:09 ` tmoran
0 siblings, 1 reply; 10+ messages in thread
From: Adrien Plisson @ 2005-03-30 8:48 UTC (permalink / raw)
Wiljan Derks wrote:
> The only advantage that hyper threading has, is that the system might be
> more responsive.
> Thus when accidentally locking one CPU at high priority, one can still break
> into the system (using the other CPU).
ok, let's release some misconceptions about HyperThreading:
an HyperThreading enabled processor DOES NOT have 2 cores.
it's not clear at all when you look at Intel's overview of
HyperThreading. they really like to tell it runs as if it were 2
processors. this may look like true for simple office tasks, which are
not computationnally intensive. unfortunately, for software
developpers used to multitasking and trying to get the most of their
system, it is evident that it is NOT 2 processors.
actually, an HT processor has one core, which makes it no faster than
a single processor. what's different is that it has 2 sets of
"states", allowing for more efficient context switches. as noted by
Wiljan, this makes the system more responsive.
but this paper does explain it in more details:
http://www.intel.com/business/bss/products/hyperthreading/server/ht_server.pdf
--
rien
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Gnat 3.15p & Windows & Hyperthreading Q
2005-03-30 8:48 ` Adrien Plisson
@ 2005-04-01 7:09 ` tmoran
0 siblings, 0 replies; 10+ messages in thread
From: tmoran @ 2005-04-01 7:09 UTC (permalink / raw)
> a single processor. what's different is that it has 2 sets of
> "states", allowing for more efficient context switches. as noted by
> Wiljan, this makes the system more responsive.
>
> but this paper does explain it in more details:
> http://www.intel.com/business/bss/products/hyperthreading/server/ht_server.pdf
That paper doesn't tell much, since it says resources unused by one
virtual cpu are available to the other. If there are lots of such
resources, then two threads ought to run with almost no interference, ie,
nearly twice as fast as sequentially. If there are bottleneck resources
then clearly things are single-file and no different than a software
implemented time-slicing multitasking. And the paper doesn't tell which.
Here's a little program which should create two definite and different
patterns on Windows/Task Manager/Performance/CPU History(s).
Compile with "gnatmake -gnato cpu2" - no optimization desired. Run Task
Manager/Performance so it displays two CPU History windows (for multi or
hyperthreaded CPUs). Start a separate Command Prompt window and run
cpu2.exe. It will run almost 100 seconds making pattern(s) on the CPU
History window(s), and some text output.
On a single CPU machine, the pattern should be like
a short spike
5 seconds zero use
38 seconds of 100% CPU use, ie, the graph pinned at the top.
21 seconds containing two spikes of CPU use.
33 seconds of 100% use.
total 97 seconds
On a multi or hyperthreaded CPU, I would expect
CPU 1 window CPU 2 window
a short spike
5 seconds zero use 5 seconds zero use
24 seconds at 100% 24 seconds with 3 spikes
40 seconds containing 5 spikes 40 seconds of zero use
24 seconds at 100% 24 more seconds of zero use
total 93 seconds
For a single CPU run, here's the text output I got:
2.85042E+07 loops/sec
start both tasks
task 1 now quiet 43.830936614
task 1 busy again 64.005100369
task 2 done 90.933717554
task 1 done 97.452995004
with Ada.Calendar,
Ada.Exceptions,
Ada.Text_IO;
procedure Cpu2 is
use type Ada.Calendar.Time;
Loops_Per_Second: Float := 0.0; -- set by Find_Speed
procedure High(T : in Duration) is
N : constant Positive := Integer(Float(T) * Loops_Per_Second);
X : Integer := 0;
begin
for I in 1 .. N loop
X := X + 1;
end loop;
end High;
procedure Low(T : in Duration) is
begin
delay T;
end Low;
task Two is
entry Start(Wavelength: in Duration;
Cycle_Count: in Natural);
end Two;
procedure Find_Speed is
T0 : constant Ada.Calendar.Time := Ada.Calendar.Clock;
begin
Loops_Per_Second := 10_000_000.0;
High(1.0);
Loops_Per_Second := Loops_Per_Second / Float(Ada.Calendar.Clock - T0);
end Find_Speed;
T0 : Ada.Calendar.Time;
task body Two is
W : Duration;
N : Natural;
begin
accept Start(Wavelength: in Duration;
Cycle_Count: in Natural) do
W := Wavelength;
N := Cycle_Count;
end Start;
delay 0.01; -- let caller run
for Cycle in 1 .. N loop
High(W / 2);
Low(W / 2);
end loop;
Ada.Text_IO.Put_Line("task 2 done"
& Duration'Image(Ada.Calendar.Clock - T0));
exception
when Oops : others =>
Ada.Text_IO.Put_Line("task two:"
& Ada.Exceptions.Exception_Information(Oops));
end Two;
begin
Find_Speed;
Ada.Text_IO.Put_Line(Float'Image(Loops_Per_Second) & " loops/sec");
T0 := Ada.Calendar.Clock;
delay 5.0;
Ada.Text_IO.Put_Line("start both tasks");
Two.Start(Wavelength => 8.0, Cycle_Count => 8);
High(25.0);
Ada.Text_IO.Put_Line("task 1 now quiet"
& Duration'Image(Ada.Calendar.Clock - T0));
delay until T0 + 64.0;
Ada.Text_IO.Put_Line("task 1 busy again"
& Duration'Image(Ada.Calendar.Clock - T0));
High(25.0);
Ada.Text_IO.Put_Line("task 1 done"
& Duration'Image(Ada.Calendar.Clock - T0));
exception
when Oops : others =>
Ada.Text_IO.Put_Line(Ada.Exceptions.Exception_Information(Oops));
end Cpu2;
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2005-04-01 7:09 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox