Threads and wait()

I’m using a multi-threaded SoundManager class (which extends ThreadGroup by the way) for sound playback using the javax.sound API. Basically, how it works is that each initialized Thread will wait() on that SoundManager object until there is a task (sound) ready to be executed and than a random Thread will be notify()ied to execute the task.

It’s all good except that I’m getting a surprisingly big performance hit, even when there are no sounds playing, which implies that all sound playback Threads are wait()ing on the object. So I’m guessing it’s not the javax.sound API’s fault.

I’m using up to 16 sound playback Threads btw. Just to clarify, should there be a performance overhead even when all these Threads are wait()ing?

Ran a profiler and found out that a native mixer thread (probably initialized by the javax.sound API) is taking up 22% of the execution time (as compared to 77% for my main thread). Horrible. And it looks like it’s still doing SOMETHING even when no sound is being played and all my sound playback Threads are wait()ing. Why?

Which profiler are you using?

Have you tried profiling a program that just loads an audio clip but doesn’t play it?

Regards,
Dr. A>

http://www.benyeoh.com/misc/mixerThread.JPG

JProfiler shows that the MixerThread is spending 14.1% of the time calling Thread.sleep() (which incurs a small overhead in itself from all that context switching) and another 7% of the processor time doing god-knows-what. And this is when NO SOUNDS ARE ACTUALLY PLAYING EVER, although there are multiple SourceDataLines open()ed and start()ed. No data is sent down the lines at anytime.

It depends on what the other threads are doing. If this is a small test bed for just sounds so the main thread is not actually doing much, then the (low) overhead of the threads will appear as a significant fraction of the time.

For example:
Thread switching take 2 ms for all the sound threads.
Main thread yields once a frame.
In a testbed we are running 100 fps.
I would expect the sound threads to be activated every 10ms. They take 2ms, giving 20% on a profile.

Example 2, a game frame takes 40ms (25fps) with one yield per frame. The thread switching in the sound still takes 2ms.
The thread switching in the sound now accounts for 5% on a profiler.

Ok, so thread switching is usually not that simple, but my point is we need more info before any conclusions on performance can be drawn - except the standard mantra of micro-benchmarking (& micro-profiling) can be tricky to interpret correctly.

  • Dom

[quote]It depends on what the other threads are doing. If this is a small test bed for just sounds so the main thread is not actually doing much, then the (low) overhead of the threads will appear as a significant fraction of the time.
[/quote]
I’m running a reasonably sized application/game so we can safely assume that the main thread IS doing quite a bit of work with game logic processing and rendering per frame.

We are only talking about 1 native mixer Thread here that is initialized by the Java sound API.

The other sound playback threads are all wait()ing on an object so they aren’t doing anything and aren’t in the equation actually.

So that’s lousy isn’t it?! That’s 20% of your processor time doing nothing but context switching…

Remember - there are 2 seperate Threads of execution here, 1 native mixer thread and the main thread. So the percentage we’re talking about (in order for it to make sense and that JProfiler is showing) is in terms of CPU slice time… Correct?

Then again, if the percentage in JProfiler is talking in terms of CPU slices, and if Thread.sleep() isn’t supposed to be taking up processor cycles while sleeping, why is it showing that it’s taking up a good 14% in the profiler?

Damn it’s late and I’m getting a little confused…

In actuality, I’m more interested in the other 7% of CPU time that the native mixer thread is using up doing something naughty when it’s not sleeping and no sound playback is happening. Looks like a waste of precious CPU cycles to me.

Some feedback and suggestions would be very appreciated. Thanks :-/

I don’t know which behavior the process scheduler in Windows XP uses, but why don’t you try and give them a amount of time when sending them to bed -> wait(100). Sounds (haha) not very reasonable, but I’d be interested in the results.

Another thing is - why do you want to have one thread for each sound??? Of course the scheduler has to look after its threads, so why don’t you make its work easier and give it only on thread at all? What about a thread-free solution? Depends on what kind of application you use that for, of course…

If I understand you right, even an uninitialized sound schedular take process time? That’d be very bad :frowning: