From: Lutz Donnerhacke <lutz@iks-jena.de>
Subject: Re: High CPU in tasking
Date: Mon, 28 Jun 2004 08:32:38 +0000 (UTC)
Date: 2004-06-28T08:32:38+00:00 [thread overview]
Message-ID: <slrncdvlt6.nt.lutz@taranis.iks-jena.de> (raw)
In-Reply-To: 2k346nF16pckjU1@uni-berlin.de
* Nick Roberts wrote:
> Not necessarily. Again, I must make some assumptions about your application,
> and the machine it is running on (specifically that it is or may be SMP),
> but it is possible that the time cost of writing each packet n times rather
> than once would be more than compensated for by the decrease in memory
> contention of multiple readers simultaneously processing the packet.
The writer task cosumes about 20% of CPU in decoding, while the reader tasks
consume about 1% in writing out. The tasking overhead is about 0.7% CPU per
task.
Before introducing minimal reading amounts, I got about 80% CPU per reader
task! And my minimal enviroment contains nine downstreams. *Orks*
You might be right in suggesting multiple buffers, but I have to postphone
measurments on this idea to a later stage. Currently the customer is waiting.
> Note that the cost of contention, mainly because of the cache flushing
> caused, could be very high compared to the cost of writing, which might
> require just one cache flush. It's interesting to note that this is a case
> where it would be useful to have compiler (or linker) support for placing
> objects in memory locations that correspond to different cache 'colours'.
Honestly, I do not understand your pragraph, but I will try to read about
caching techniques. Thanks for the hint.
[different priorities]
>> Why? This would cause the writer to overwrite the ringbuffer
>> without any reading access.
>
> Not unless your code is faulty. You must not rely upon priority or
> expectations of the executional progress of tasks to replace proper
> synchronisation control.
Correct. I'll try this out. It might be helpful in improving my mental model
of the process itself.
> I think the priority adjustments I suggested are also invalidated by the
> information you have given (above). I won't explain why I made the
> suggestion, as I don't want to confuse you, but trust me that there was a
> good reason.
;-)
>> The whole program is event triggered. There are no free running
>> code sequences. The only effect I can imagine will be a deadlock ;-)
>
> Not unless your code is faulty.
My code is definitly broken. I get tasking errors :-(
> You must not rely upon priority or expectations of the executional
> progress of tasks to replace proper synchronisation control. (Hope I
> don't sound like a parrot :-)
At the moment I do only rely on the proper synchronisation control of a
protected type with entry families. But I'll try to improve this using your
ideas.
> If you would be willing to show the relevant code, and describe your
> application's goals and design in a bit more detail, I'd be very interested.
package Ringbuffers is
pragma Elaborate_Body;
-- Position is not monotonic in order to process infinite streams.
type Position is mod 2**31;
-- Entry families are limited by
-- System.Tasking.Protected_Objects.Max_Protected_Entry (GNAT)
-- so a level of indirection is necessary
type Protected_Entry is range 1 .. 100;
type Entry_Position is array(Protected_Entry) of Position;
type Entry_Boolean is array(Protected_Entry) of Boolean;
pragma Pack(Entry_Boolean);
No_Free_Entry : exception;
type Main_Statistic_Type is record
write : Position;
readers : Natural;
end record;
type Statistic_Type(connected : Boolean) is record
write : Position;
case connected is
when False => null;
when True =>
behind : Natural;
missed : Natural;
note : Boolean;
end case;
end record;
protected type Ringbuffer(Size : Positive; Minimum_Output : Natural) is
procedure Register(index : out Protected_Entry); -- raise No_Free_Entry
procedure Unregister(index : Protected_Entry);
function Statistics return Main_Statistic_Type;
procedure Notify(index : Protected_Entry);
function Statistics(index : Protected_Entry) return Statistic_Type;
procedure Put(data : in String);
entry Get(Protected_Entry)(
notify : out Boolean;
data : out String;
last : out Natural;
missed : out Natural
);
private
write : Position := Position'First;
read : Entry_Position;
usage, notification : Entry_Boolean := (others => False);
buffer : String(1 .. Size);
end Ringbuffer;
end Ringbuffers;
next prev parent reply other threads:[~2004-06-28 8:32 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-06-24 15:43 High CPU in tasking Lutz Donnerhacke
2004-06-24 17:00 ` Nick Roberts
2004-06-24 20:25 ` Lutz Donnerhacke
2004-06-24 21:56 ` Nick Roberts
2004-06-25 7:34 ` Lutz Donnerhacke
2004-06-25 17:03 ` Nick Roberts
2004-06-28 8:32 ` Lutz Donnerhacke [this message]
2004-06-29 17:26 ` Nick Roberts
2004-06-30 12:26 ` Lutz Donnerhacke
2004-06-30 23:39 ` Randy Brukardt
2004-07-01 7:02 ` Lutz Donnerhacke
2004-06-25 21:15 ` Mark Lorenzen
2004-06-26 8:01 ` Wojtek Narczynski
2004-06-28 8:17 ` Lutz Donnerhacke
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox