From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,3e3949298ed3b36 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news2.google.com!proxad.net!213.200.89.82.MISMATCH!tiscali!newsfeed1.ip.tiscali.net!feed.news.tiscali.de!news.netplace.de!news-FFM2.ecrc.net!news.iks-jena.de!not-for-mail From: Lutz Donnerhacke Newsgroups: comp.lang.ada Subject: Re: High CPU in tasking Date: Mon, 28 Jun 2004 08:32:38 +0000 (UTC) Organization: IKS GmbH Jena Message-ID: References: <2k0fllF160eotU1@uni-berlin.de> <2k1114F15uoj8U1@uni-berlin.de> <2k346nF16pckjU1@uni-berlin.de> NNTP-Posting-Host: taranis.iks-jena.de X-Trace: branwen.iks-jena.de 1088411558 10947 217.17.192.37 (28 Jun 2004 08:32:38 GMT) X-Complaints-To: usenet@iks-jena.de NNTP-Posting-Date: Mon, 28 Jun 2004 08:32:38 +0000 (UTC) User-Agent: slrn/0.9.8.0 (Linux) Xref: g2news1.google.com comp.lang.ada:1964 Date: 2004-06-28T08:32:38+00:00 List-Id: * 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;