DSoundAudioIODevice::run using up all my cycles


#1

These two are using a lot of cpu time, is this normal and unavoidable?
My buffer size is 1024.

	CPU Time	Module	Function (Full)
juce::DSoundAudioIODevice::run	35.1%	Radon.exe	juce::DSoundAudioIODevice::run(void)
juce::DSoundInternalOutChannel::service	13.8%	Radon.exe	juce::DSoundInternalOutChannel::service(void)

The next most active DSP-related stuff is only 13%.

For reference, the DSound routines total 14% of my total quad-core CPU util. Something’s awry surely?


#2

It does a lot of sleeping in that loop, unless you’re trying to use a low latency and it’s struggling to keep up, perhaps?


#3

Well the buffer size is a healthy 1024.

Is such a small sleep going to incur thrashing between threads? Or maybe not… 95% of the time is on that one thread. I’ll try and do more tests.


#4

So VTune is saying that 32% of the time is spent on that sleep call

Line	Source	CPU Time
252331	                    if (--count <= 0)	
252332	                    {	
252333	                        Sleep (1);	31.8%
252334	                        count = maxCount;	
252335	                    }	

I don’t understand the context of this code, but should my dsp code go in a separate thread perhaps?


#5

Sounds fine to me. Not sure what you mean about your DSP code - if you’re doing a lot of work on the audio thread, then surely it’s no surprise that that thread is using a lot of CPU?


#6

The dsp stuff takes about a third as much time as that spent spinning in those sleep calls, and clearly it can’t be doing DSP number crunching while the same thread is sleeping.

My concern is that all this sleeping is contributing far too much to the cpu usage of my synthesizer voice. My knowledge of c++ threads is slim, but why are the sleep calls necessary? Can’t the OS schedule things well enough?


#7

eh? sleep doesn’t contribute to the cpu load. That’s the whole point. While it’s sleeping, the scheduler shouldn’t be counting that time as cpu time. Your profiler will of course tell you that it’s ‘busy’ inside the sleep call, but in reality it’s not tying up any cpu resources, that’s why it’s there…


#8

Well, it’s Win32 horror going on here.
Sleep(1) in windows is not doing “Sleep 1 ms” like you expect. It calls tell the windows’s kernel to sleep your current thread, and resume it, at least 1ms from now.
And since, there is a usually a lot of thread waiting to run at any given time, you’ll likely wait much more than the specified 1ms duration.
So, as Jules said, this is perfectly correct, since you are giving back your remaining thread timeslice to the system, so the CPU can be used for another, more important, thread.

You should read: http://www.geisswerks.com/ryan/FAQS/timing.html

Jules, you could consider using SwitchToThread whenever possible, for the reason explained below, instead of the old fashionned Sleep() call (or even better, use a WaitForSingleObject on a the soundcard’s async IO, so you actually never “sleep”)
The issue is that since Vista is out, the kernel is doing a lot of statistics on the thread API usage (yes that sound crazy), and when you’re doing a lot of Sleep() calls, you’ll rank lower in the scheduler queue.

Over the running time, our realtime streaming client started to behave way way slower on Vista, and this was due to our sched_yield()/Sleep() calls. When we rewrote the application to use events whenever possible, the performance resumed.


#9

Thanks for the input. I’ve actually read that article at some point a couple of years ago.
It’s clear that sleeping isn’t the same as waiting for a lock (I suppose I should have chosen another word than ‘spinning’), but it will act exactly like one if processing is trying to happen on the same thread. I want the DSP routines (i.e. the render callbacks) to be able to use 99.5% of the cpu if necessary… but how can that happen if the DSound routines on that thread are relinquishing it’s cpu time?
Beside which, a significant amount of the time in those two DSound routines is NOT idle (about 30%); I really don’t know where those cycles are going …yet. (I’ve been profiling other parts of my app but I’ll return to this soon enough)

Sorry if I’m being a pain about this! :smiley:


#10

I’m struggling to see your point… Doing some sleeping in that thread is absolutely essential to prevent the system from locking up - it’s a high (or even realtime?) priority thread, so it can’t sit there spinning. But I don’t understand why you think the sleep calls are somehow cheating you out of getting any cpu action? DSound is crap for low-latency audio anyway, so your buffer size will be have to be at least 10ms - if it sleeps for 1ms of that time, your callback can still hammer the cpu for 90% of its capacity, which is all you could reasonably expect to get.