Thread::yield() performance OS X


#1

I’m having to get a lot of MessageManagerLocks in my program and I noticed that my CPU usage is bouncing all over the place. I used the time profiler and found that sched_yield() is taking up lots of CPU. It is originating from MessageManagerLock::attemptLock when it calls Thread::yield().

I did some reading around and found that sched_yield() can take up CPU if there is nothing available to yield to. I simply switched the sched_yield() in Thread::yield() to a sleep (1) and I’m getting much better CPU usage:

[attachment=0]Screen Shot 2012-12-14 at 2.34.37 PM.png[/attachment]

EDIT: I’m using OS X 10.8.2


#2

Better would be not to take the message manager lock. Is it absolutely necessary? Couldn’t it be done a different way?


#3

I never really thought about trying to get rid of the MessageManagerLock. I will look into that right now.

That being said, would the yield function actually be better off with sched_yield() rather than a sleep function of whatever timing?


#4

If you can explain why you’re taking the lock I will attempt to come up with an alternative.

No clue, really.

Looking over MessageManager::attemptLock…wow…I would stay far away from that function it is doing a hell of a lot! This is nothing like a CriticalSection, it is tying up the entire event loop by posting a custom message to the system queue.


#5

I have some components that regularly request data from another thread that I want to avoid blocking. These components are requesting the data and then waiting for a response from the non blocking thread. They then need to draw themselves ASAP which is where I was waiting for the MessageManagerLock. I’m changing them now so that they call redraw on an async update instead to see how that works.


#6

You should redraw on an async update :lol:


#7

Alright, thanks for the suggestion.


#8

Actually, now I remember that AsyncUpdater::triggerAsyncUpdate can block the audio thread / calling thread. The reason is that internally it calls SendMessage (on Windows at least). That’s why in VFLib, for the GuiCallQueue I use a separate thread for calling triggerAsyncUpdate, and use a vf::CallQueue to activate it.


#9

I’ve been thinking about this in the context of audio plugins lately, so I thought I’d post my notes on this on a new thread here.


#10

Dead link!