vvopensource icon indicating copy to clipboard operation
vvopensource copied to clipboard

Excessive wakeups when using OSCInPort

Open markwheeler opened this issue 9 years ago • 2 comments

I'm using a single OSCInPort to receive OSC messages and I noticed that it's responsible for a lot of thread sleeping / waking.

With the default interval of 0.01secs I'm seeing around 170 wake-ups per second in Activity Monitor. Extending the interval does of course reduce the wake-ups but it still seems like a lot.

Having a lot of wake-ups causes a warning in the Console along the lines of 'process Xxxxx[yyyy] caught causing excessive wakeups.' 'Maximum permitted wakeups rate (per sec): 150'.

As far as I can tell this message is just a warning (doesn't seem to have any effect) and it usually triggers when the wakeups count actually goes quite a lot higher than 150, but still it got me thinking maybe this was something worth optimising.

What do you think, is this something that could be done a different way while still being responsive to incoming messages?

For reference, there's some good info on this page about monitoring wakeups etc: https://developer.apple.com/library/mac/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/Timers.html

markwheeler avatar Feb 16 '16 06:02 markwheeler

hi mark-

sorry for the delay!

  • you're absolutely correct, i could definitely reduce the "energy impact" of VVOSC by modifying its backend from one that sleeps a thread to one that installs something on a runloop/something that "creates some kind of event" on receipt of network data. specifically, this sort of different pattern would eliminate the need to sleep/wake threads.
  • to test performance, i built a quick test app with the AsyncUdpSocket class from the CocoaAsyncSocket framework (on the backend, this uses a CFSocket installed on a runloop to receive notifications- as far as i can tell, this is what you're suggesting i look into, and CocoaAsyncSocket is a well-regarded framework with respect to performance/efficiency so i'm assuming its implementation is pretty good). as you predicted, this has somewhere around 0 wakes/second (a much lower energy usage profile!), and slightly lower CPU usage than VVOSC when idle (~1% vs. ~0%).
  • however, under load, the performance of this setup appears to be substantially worse- specifically, the CPU usage is between 1.5x and 10x higher than what i see in the approach used by VVOSC (~1.5x higher when simply scrubbing a single slider in TouchOSC on an ipad, ~10x higher when sending around 10k OSC messages/second). i don't think that this is the result of any problems with CocoaAsyncSocket.framework- rather, i think this is the result of the difference in the basic patterns between the approaches (i profiled the sample app, the thread with the socket manager alone was responsible for ~3x the CPU usage of the app using VVOSC).

i'm all for making stuff faster/more efficient, but it's not clear to me that this sort of modification would be a net win when all things are considered. if you think i overlooked something, or you have any other suggestions, ideas, or things you think i should try, i'd love to hear them!

mrRay avatar Feb 22 '16 12:02 mrRay

Big thanks for looking into this in such depth!

It all totally makes sense, I must admit I hadn't really thought about super-high numbers of OSC messages – I mostly use VVOSC to receive user input from buttons so the number of input messages I get in my app is really low.

I guess you could have the option to use either 'mode' when initialising a port but I can see that could be quite a bit of effort to implement and may well complicate the code more than is worthwhile.

Really appreciate you taking the time to test this out and report back though :)

markwheeler avatar Feb 24 '16 02:02 markwheeler