Discussion:
[omniORB] Many context switches in idle application
Lucca-Daniau, Marc-Francois (GE Healthcare)
2010-11-23 20:54:17 UTC
Permalink
Hello,

Configuration : OmniORB 4.1.4 C++ / Visual '98 6.0 SP6 / Windows XP
embedded SP3
Host : Xeon Pentium 4 - HT disabled (so one logical core)

Our application has >30 processes, each processs creates and activates
from one to several servants, using only the default root POA. OmniNames
is used as the naming service to interconnect.

Using MS Sysinternals Process Explorer, we see that each process has ~70
context switches / second when the application is idle, with almost no
CPU usage and no page fault.

Debugging the OmniORB core shows that an Omni thread is iterating
quickly around a select() with a short timeout:

SocketCollection.cc(929):

CORBA::Boolean
SocketCollection::Select() {
...
if (rfds.fd_count) {
// Windows select() ignores its first argument.
count = select(0, &rfds, 0, 0, &timeout);
}

We tried to run the application after making the select() to block:

count = select(0, &rfds, 0, 0, NULL /*&timeout*/);

Application works well after that patch, and context switches go down to
1~2 per second for each process, due to other application threads that
perform some periodic work at a low rate.

We tried to understand why that select should not block in OmniORB
design, we start to think this is for the "poll" ORB feature
(application uses only blocking invocations), but we are not sure yet.

Any idea ?

Regards,

Marc-F. LUCCA-DANIAU
General Electric Healthcare Buc

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20101123/db1908c3/attachment.htm
Duncan Grisby
2010-11-25 03:34:30 UTC
Permalink
On Tue, 2010-11-23 at 15:54 +0100, Lucca-Daniau, Marc-Francois (GE
Post by Lucca-Daniau, Marc-Francois (GE Healthcare)
Using MS Sysinternals Process Explorer, we see that each process has
~70 context switches / second when the application is idle, with
almost no CPU usage and no page fault.
That's expected behaviour on Windows. Can you explain why you consider
it a problem? As you say, it doesn't contribute to any noticeable CPU
usage.
Post by Lucca-Daniau, Marc-Francois (GE Healthcare)
Debugging the OmniORB core shows that an Omni thread is iterating
[...]
Post by Lucca-Daniau, Marc-Francois (GE Healthcare)
We tried to understand why that select should not block in OmniORB
design, we start to think this is for the "poll" ORB feature
(application uses only blocking invocations), but we are not sure yet.
The select wakes up periodically because the ORB needs to asynchronously
add and remove sockets from the set that are being watched by select().
In the default thread-per-connection mode, whenever a call is
dispatched, the associated socket is added to the set to be watched by
the select() loop, in case the client sends an interleaved concurrent
request on the same connection. When the dedicated thread returns from
the upcall, it takes the connection back out of the set used in
select(). Similarly, in thread pool mode, the select loop watches all
the idle connections. When a call comes in, the socket is taken out of
the set, but then has to be asynchronously added back in when the call
arguments have been unmarshalled.

When things are otherwise idle, Unix platforms send the thread in select
(or poll) into permanent sleep, and use a pipe to wake it up again if
need be. There's nothing equivalent on Windows that can be used to wake
it up, so the thread stays a little bit active all the time.

The default timeout is 50 milliseconds, which is a good compromise
between responsiveness and low processing overhead for most
applications. You can change that by setting the connectionWatchPeriod
to a different value. It's specified in microseconds, so setting it to
1000000 will cause the thread to wake up every second, for example.

Cheers,

Duncan.
--
-- Duncan Grisby --
-- ***@grisby.org --
-- http://www.grisby.org --
Loading...