* 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