comp.lang.ada
 help / color / mirror / Atom feed
* Performance of many concurrent delay() calls
@ 2016-11-07 18:52 Olivier Henley
  2016-11-07 19:04 ` J-P. Rosen
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Olivier Henley @ 2016-11-07 18:52 UTC (permalink / raw)


Hi to all,

Does calling [loop and delay(1.0)] for each of many thousand connected clients (gnoga/simple components) is a huge performance hit or not?

If so, what is the recommended way to implement a periodic, every sec, procedure that has to run for every clients; instantiate a single main task looping, delay(1.0), over all connections data and call the wanted procedure... probably?

Thx. 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Performance of many concurrent delay() calls
  2016-11-07 18:52 Performance of many concurrent delay() calls Olivier Henley
@ 2016-11-07 19:04 ` J-P. Rosen
  2016-11-07 19:13 ` Olivier Henley
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: J-P. Rosen @ 2016-11-07 19:04 UTC (permalink / raw)


Le 07/11/2016 à 19:52, Olivier Henley a écrit :
> Does calling [loop and delay(1.0)] for each of many thousand
> connected clients (gnoga/simple components) is a huge performance hit
> or not?

Like any question about performance, this depends on the target, OS, and
compiler used. The only good advice is: do measurements.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Performance of many concurrent delay() calls
  2016-11-07 18:52 Performance of many concurrent delay() calls Olivier Henley
  2016-11-07 19:04 ` J-P. Rosen
@ 2016-11-07 19:13 ` Olivier Henley
  2016-11-07 20:57 ` Dmitry A. Kazakov
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Olivier Henley @ 2016-11-07 19:13 UTC (permalink / raw)


Ok but sometimes such pratice are a general nono. I am only looking for a rule of thumb here; I am on a relatively safe side or I am just insane to even think about such solution.

Thx. 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Performance of many concurrent delay() calls
  2016-11-07 18:52 Performance of many concurrent delay() calls Olivier Henley
  2016-11-07 19:04 ` J-P. Rosen
  2016-11-07 19:13 ` Olivier Henley
@ 2016-11-07 20:57 ` Dmitry A. Kazakov
  2016-11-07 21:30 ` Florian Weimer
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Dmitry A. Kazakov @ 2016-11-07 20:57 UTC (permalink / raw)


On 2016-11-07 19:52, Olivier Henley wrote:

> Does calling [loop and delay(1.0)] for each of many thousand
> connected  clients (gnoga/simple components) is a huge performance hit or not?

I am not sure what you mean. Simple Component's server is specifically 
designed to handle multiple/all connections from one task. A delay on 
the context of that task is not a performance hit it is a catastrophe.

> If so, what is the recommended way to implement a periodic, every
> sec,  procedure that has to run for every clients; instantiate a single main
> task looping, delay(1.0), over all connections data and call the wanted
> procedure... probably?

That depends on what the periodic procedure is supposed to do. You 
cannot read any data from an external task, but you can queue data to 
send if the client's output buffer is not full. You can also allocate 
secondary buffers, there is a primitive operation called when a portion 
of data is sent. It is called on the server's task context and can be 
used to push data from the secondary buffer(s) into the freed portion of 
the primary buffer.

As for creating an external task for each client, that would defeat the 
purpose of the design (an OS can have a large number of sockets and only 
a limited number of tasks). So if any external tasks created they should 
loop over multiple clients.

How many external tasks and how many server tasks is a question of 
balance between CPU / Ethernet controller / network load. As J-P said, 
there is no way to foresee it. You have to measure.

Finally, there is a simple method of having non real-time *short* 
periodic activity per client. You override receive or send callback and 
check if the period is expired since latest periodic call. If yes you 
note the time (in the client) do that call again. If there is steady 
socket I/O that would work.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Performance of many concurrent delay() calls
  2016-11-07 18:52 Performance of many concurrent delay() calls Olivier Henley
                   ` (2 preceding siblings ...)
  2016-11-07 20:57 ` Dmitry A. Kazakov
@ 2016-11-07 21:30 ` Florian Weimer
  2016-11-07 22:42 ` Jeffrey R. Carter
  2016-11-09 15:50 ` Olivier Henley
  5 siblings, 0 replies; 8+ messages in thread
From: Florian Weimer @ 2016-11-07 21:30 UTC (permalink / raw)


* Olivier Henley:

> Does calling [loop and delay(1.0)] for each of many thousand connected
> clients (gnoga/simple components) is a huge performance hit or not?

Periodic wakeups are considered bad for battery life and also
negatively impact density of VMs (and containers).

> If so, what is the recommended way to implement a periodic, every sec,
> procedure that has to run for every clients; instantiate a single main
> task looping, delay(1.0), over all connections data and call the
> wanted procedure... probably?

I think this depends on what has to be done every second, and to what
degree these actions depend on other resources.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Performance of many concurrent delay() calls
  2016-11-07 18:52 Performance of many concurrent delay() calls Olivier Henley
                   ` (3 preceding siblings ...)
  2016-11-07 21:30 ` Florian Weimer
@ 2016-11-07 22:42 ` Jeffrey R. Carter
  2016-11-09 15:50 ` Olivier Henley
  5 siblings, 0 replies; 8+ messages in thread
From: Jeffrey R. Carter @ 2016-11-07 22:42 UTC (permalink / raw)


On 11/07/2016 11:52 AM, Olivier Henley wrote:
>
> Does calling [loop and delay(1.0)] for each of many thousand connected
> clients (gnoga/simple components) is a huge performance hit or not?

Both loop and delay are statements, and are not called.

> If so, what is the recommended way to implement a periodic, every sec,
> procedure that has to run for every clients; instantiate a single main task
> looping, delay(1.0), over all connections data and call the wanted
> procedure... probably?

 From the context of Gnoga, a connection should usually spend most of its time 
waiting for the user to do something. I'm going to presume that you want to do a 
periodic update of all windows, with the updates not being synchronized, since 
you're using a relative delay. In that case, having a task per connection that 
spends most of its time in a delay and does something fairly quick when not 
should not be a problem. You'd have a task component in the connection data that 
would periodically update something in the connections window. You'd want a way 
to keep the task from running until the window is set up.

type App_Info;
type App_Ptr is access all App_Info;

task type Updater (App : App_Ptr) is
    entry Start;
    entry Stop;
end Updater;

type App_Info is new Gnoga.Types.Connection_Data_Type with record
    Window : Gnoga.Gui.Window.Pointer_To_Window_Class;
    View   : Gnoga.Gui.View.View_Type;
    Form   : Gnoga.Gui.Element.Form.Form_Type;
    Count  : Gnoga.Gui.Element.Form.Number_Type;
    Update : Updater (App => App_Info'Unchecked_Access);
end record;

task body Updater is
    Count : Natural := 0;
begin -- Updater
    accept Start;

    Forever : loop
       select
          accept Stop;

          exit Forever;
       or
          delay 1.0;

          Count := Count + 1;
          App.Count.Value (Value => Count);
       end select;
    end loop Forever;
end Updater;

In the on-connect handler, after assigning Window and creating View, Form, and 
Count, you'd call Update.Start. Your on-quit handler would call Update.Stop.

As this seems the clearest and simplest approach, you should try it first and 
see if it meets your timing requirements.

-- 
Jeff Carter
"I certainly have not the talent which some people possess, ...
of conversing easily with those I have never seen before."
Pride and Prejudice
121


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Performance of many concurrent delay() calls
  2016-11-07 18:52 Performance of many concurrent delay() calls Olivier Henley
                   ` (4 preceding siblings ...)
  2016-11-07 22:42 ` Jeffrey R. Carter
@ 2016-11-09 15:50 ` Olivier Henley
  2016-11-09 23:15   ` Jeffrey R. Carter
  5 siblings, 1 reply; 8+ messages in thread
From: Olivier Henley @ 2016-11-09 15:50 UTC (permalink / raw)


Thank you all for the replies.

@Jeffrey

Right now I am doing the following inside the On_Connect handler

loop
  if Main_Window.Connection_Data = null then
    exit;
  end if;
         
  App_Central.Process_Message (App_Data);

  delay 1.0;
end loop;

Is it fine or the usage of a task is strongly recommended and for what reasons? 

Thank you,

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Performance of many concurrent delay() calls
  2016-11-09 15:50 ` Olivier Henley
@ 2016-11-09 23:15   ` Jeffrey R. Carter
  0 siblings, 0 replies; 8+ messages in thread
From: Jeffrey R. Carter @ 2016-11-09 23:15 UTC (permalink / raw)


On 11/09/2016 08:50 AM, Olivier Henley wrote:
>
> Right now I am doing the following inside the On_Connect handler
>
> loop
>   if Main_Window.Connection_Data = null then
>     exit;
>   end if;

exit when Main_Window.Connection_Data = null;

>   App_Central.Process_Message (App_Data);
>
>   delay 1.0;
> end loop;
>
> Is it fine or the usage of a task is strongly recommended and for what reasons?

I don't know. IIUC, Gnoga creates a task to call the on-connect handler, and 
you're keeping that task busy in the handler for the life of the connection. I 
don't know what the effect of that on the Gnoga internals might be. If it works 
OK for lots of connections, then it's probably OK. Botton would know for sure. 
Personally, I'd rather not tie up a task from a library without knowing more 
about what the consequences are.

-- 
Jeff Carter
"I've seen projects fail miserably for blindly
applying the Agile catechism: we're Agile, we
don't need to stop and think, we just go ahead
and code!"
Bertrand Meyer
150

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-11-09 23:15 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-07 18:52 Performance of many concurrent delay() calls Olivier Henley
2016-11-07 19:04 ` J-P. Rosen
2016-11-07 19:13 ` Olivier Henley
2016-11-07 20:57 ` Dmitry A. Kazakov
2016-11-07 21:30 ` Florian Weimer
2016-11-07 22:42 ` Jeffrey R. Carter
2016-11-09 15:50 ` Olivier Henley
2016-11-09 23:15   ` Jeffrey R. Carter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox