comp.lang.ada
 help / color / mirror / Atom feed
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;



  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