comp.lang.ada
 help / color / mirror / Atom feed
From: Mark Lorenzen <mark.lorenzen@ofir.dk>
Subject: Re: High CPU in tasking
Date: 25 Jun 2004 23:15:17 +0200
Date: 2004-06-25T23:15:17+02:00	[thread overview]
Message-ID: <m3zn6rmja2.fsf@0x52b411d3.dhcp.kabelnettet.dk> (raw)
In-Reply-To: slrncdltli.nr.lutz@taranis.iks-jena.de

Lutz Donnerhacke <lutz@iks-jena.de> writes:

> In order to stop others falling into the same mistake, I debugged several
> days.
> 
> I wrote an data stream decoder and output (via TCP) manifolder using Ada
> tasking and a protected ringbuffer. The whole application word fine, but the
> CPU load increased linear on input load and dramatically over the number of
> output queues.
> 
> Debugging turned out:
>   - Every writing to the ringbuffer wakes up all reader tasks.
>   - That's why the reader buffers were filled with only the little data amount
>     just written.
>   - Tasking overhead caused the CPU load.
> 
> Two solutions (used both):
>   - The ringbuffer got a minimum reading length => Fewer wakeups.
>   - The writer task collect a lot of data before writing
>     => Fewer checks for wakeup.
> 
> The ratio of tasking events before and after the change is about 30:1.
> 
> Conclusion:
>   When implementing tasking synchonisation with protected objects,
>   keep in mind, that the standard Ada tasking model generates a near real
>   time experience, which is mostly not required.
> 
> HTH

These are some very good observations regarding soft- vs hard
real-time systems. In soft real-time systems we often want high
throughput and gladly sacrifice responsiveness.

A favorite design of mine, is to have one task for each interface,
that encapsulates all the horrible properties of the interface
f.x. TCP's chopping of data and so on. When a complete message,
telemetry frame or whatever has been read, it can be put into a queue
for further treatment. Just like when your writer collects a lot of
data before writing.

If it is necessary with a lot of readers, you may find out that one
task for each reader is not the right solution, but one task for many
readers should be used. In very high performance systems, you may want
one task for each network interface card on the computer in order to
avoid that the tasks compete for the limited resource (i.e. the
NIC). One task would then serve many TCP sessions and buffer write
requests in a way so that it can write large chunks at a time.

Do not underestimate the overhead from tasking.

Regards,
- Mark Lorenzen



  parent reply	other threads:[~2004-06-25 21:15 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
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 [this message]
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