Csound Csound-dev Csound-tekno Search About

Re: [Cs-dev] Object design question for API use

Date2006-04-08 03:30
From"Michael Gogins"
SubjectRe: [Cs-dev] Object design question for API use
OK, you had mentioned this earlier, sorry I forgot.

However, every Csound thread you spawn will consume a small amount of 
overhead to manage the thread. Unless you have a multiple CPU machine, it is 
always more efficient to keep everything in a single thread.

Have you considered using ONE Csound thread (which would also serve the 
GUI), but use additional threads for time-consuming work? In that case:

csoundCompile(csound);
startWorkerThreads();
while(performing) {
    Event *eventToHandle = pollForGuiEvents();
    if(eventToHandle->isTimeConsuming()) {
        unfinishedWorkQueue.enqueue(eventToHandle);
    } else {
        dispatchRegularGuiEvents(event);
    }
    if (!finishedWorkQueue.isEmpty()) {
        Event *finishedWork = finishedWorkQueue.dequeue();
         putFinishedWorkIntoGuiOrCsound(finishedWork);
    }
    csoundPerformKsmps(csound);
};

void sampleWorkerThreadRoutine() {
    while(working) {
        Event *work = unfinishedWorkQueue.dequeue();
        handleEvent(work);
        finishedWorkQueue.enqueue(work);
    }
}

Here, you can have multiple threads running which do not interfere with the 
Csound rendering thread, but you still don't need mutexes or any other 
thread synchronization code except in TWO places -- enqueuing finished work 
from worker threads onto the finished work queue, and dequeing finished work 
from the finished work queue.

Sometimes you absolutely need threads, but it's always best to keep them to 
a minimum and to keep the code as dead simple as possible.

Of course, if you have a 4 CPU (or more) machine you might be able to run 
multiple Csound rendering threads and mix their output signals together 
before sending the sum to the audio output. Is this what you are trying for? 
Even in this case, you don't need many mutexes -- you would dequeue audio 
from each Csound instance, mix it, and enqueue it to the audio output, just 
as with work in the above example. It's a little tricker than that because 
you have to keep the audio output blocks in order and mix them inside one 
more mutex.

Regards,
Mike

----- Original Message ----- 
From: "Iain Duncan" 
To: 
Sent: Saturday, April 08, 2006 1:31 AM
Subject: Re: [Cs-dev] Object design question for API use


>> Why didn't you drive performance in ksmps blocks? Then you would need no 
>> mutex, and your loop conceptually would look like this:
>>
>> csoundCompile(csound);
>> while(performing) {
>>     pollForGuiEvents();
>>     csoundPerformKsmps(csound);
>> }
>>
>> The shared data you need would be host data in Csound. "pollForGuiEvents" 
>> would be Fl::wait(0) or the equivalent. It can't get more efficient than 
>> this.
>>
>> The critical point here is the GUI also is not running in its own thread; 
>> GUI events are dispatched only when pollForGuiEvents (or whatever it is 
>> for that specific GUI framework, they all have something like this) is 
>> called. There is only one thread in your application, and it takes turns 
>> handling GUI-related events (in pollForGuiEvents()) which invoke 
>> callbacks that change variables, etc., still in the same thread, and 
>> handling Csound-related events (in csoundPerformKsmps()).
>>
>> This only works if your GUI is only running when Csound is running. If 
>> your GUI needs to run when Csound is not running, this scheme will not 
>> work in this simple form. But, you can still modify it to work in that 
>> case, if the event handler that starts Csound running performs the above 
>> code, which will keep handling GUI events. Then when Csound finishes 
>> performing, or if the use sets the "performing" variable to false, then 
>> the regular GUI event loop will handle events again.
>>
>> Is this clear? Or is there some reason why this just will not work for 
>> you?
>
> Thanks Michael. Yes, the above is clear, and I did get the above design
> working with your help a while back. The questions now are for a rather
> ambitious design in which I intend to have multiple client guis and i/o
> modules interacting with a server controller that may in turn spawn
> multiple csound threads, with csound threads running at a high priority
> and input buffered so that client input modules can not block csound
> even under heavy load. Ultimately I will consider it working when a
> client gui can drop a *large* sound file into csound from disk without
> interrupting playback. This requires buffering input to csound through
> queues, etc. I have the basics working, but as I am still learning this
> kind of stuff, I keep changing the underlying architecture. I intend to
> make this a public project once I have a decent base architecture that
> is somewhat stable and passes my tests.
>
> Iain
>
>
> -------------------------------------------------------
> This SF.Net email is sponsored by xPML, a groundbreaking scripting 
> language
> that extends applications into web and mobile media. Attend the live 
> webcast
> and join the prime developer group breaking into this new coding 
> territory!
> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
> _______________________________________________
> Csound-devel mailing list
> Csound-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/csound-devel
> 




-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Csound-devel mailing list
Csound-devel@lists.sourceforge.net

Date2006-04-08 11:46
FromIain Duncan
SubjectRe: [Cs-dev] Object design question for API use
> OK, you had mentioned this earlier, sorry I forgot.
> 
> However, every Csound thread you spawn will consume a small amount of
> overhead to manage the thread. Unless you have a multiple CPU machine,
> it is always more efficient to keep everything in a single thread.
> 
> Have you considered using ONE Csound thread (which would also serve the
> GUI), but use additional threads for time-consuming work? In that case:

What you describe ( thanks for taking the time to do so ) is very
similar to what I am doing. I have a csound thread and a controller
thread which together act as the server, and then client user interface
threads, currently just FLTK but with the aim of them also including
input and output modules for midi, osc, serial and network connections.
All clients send messages to the controller, the controller translates
and dispatches messages to the csound object/thread, both data writing
and data reading requests, and the csound thread only takes a certain
number of messages off its queue per kpass allowing it to perform
properly even if a lot of input is backed up in the queue ( perhaps say
dropping an audio file into csound while it is running ). The number of
mutexes and threads are kept low, really just one per object to protect
its queue, and more importantly, the use of the mutexes is limited to
the infrequently occuring input events, and one lock/unlock per kpass.
The only time the threads use them is when queueing/dequeing messages,
and for transport control ( obviously we need to keep a tight reign on
how we start and stop csound, etc ). I realize that I make some
sacrifices in efficiency to have this flexibility, but I am intending in
the long run to have a base architecture that can be used for multi-cpu,
multi-csound, multi-computer situations, and that will likely include
blending of audio from seperate csound threads as well. The underlying
purpose is to better enable group improvisation of computer music beyond
what standalone unconnected boxes allow. So far the tests seem to be
working well, the extra overhead of the multiple objects with queues is
neglible compared to the audio processing ( on the order of a percent or
two cpu use. ) This system also allows us to have displays update even
if the data is being controlled by some other user or process.

Thanks again for your input on this Michael. When I ( finally ) have
what I think is a base architecture hashed out I will put the code up
and would be happy to get your feedback. Mostly it's a lot of learning
right now. ; )

Iain


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Csound-devel mailing list
Csound-devel@lists.sourceforge.net