Thanks Christof, that's very helpful. iain
On Sat, Oct 24, 2020 at 5:53 PM Christof Ressi <[email protected]> wrote: > But if you're still worried, creating a pool of objects of the same size > is actually quite easy, just use a https://en.wikipedia.org/wiki/Free_list > . > > Christof > On 25.10.2020 02:45, Christof Ressi wrote: > > A) Am I right, both about being bad, and about clock pre-allocation and > pooling being a decent solution? > B) Does anyone have tips on how one should implement and use said clock > pool? > > ad A), basically yes, but in Pd you can get away with it. Pd's scheduler > doesn't run in the actual audio callback (unless you run Pd in "callback" > mode) and is more tolerant towards operations that are not exactly realtime > friendly (e.g. memory allocation, file IO, firing lots of messages, etc.). > The audio callback and scheduler thread exchange audio samples via a > lockfree ringbuffer. The "delay" parameter actually sets the size of this > ringbuffer, and a larger size allows for larger CPU spikes. > > In practice, allocating a small struct is pretty fast even with the > standard memory allocator, so in the case of Pd it's nothing to worry > about. In Pd land, external authors don't really care too much about > realtime safety, simply because Pd itself doesn't either. > > --- > > Now, in SuperCollider things are different. Scsynth and Supernova are > quite strict regarding realtime safety because DSP runs in the audio > callback. In fact, they use a special realtime allocator in case a plugin > needs to allocate memory in the audio thread. Supercollider also has a > seperate non-realtime thread where you would execute asynchronous commands, > like loading a soundfile into a buffer. > > Finally, all sequencing and scheduling runs in a different program > (sclang). Sclang sends OSC bundles to scsynth, with timestamps in the near > future. Conceptually, this is a bit similar to Pd's ringbuffer scheduler, > with the difference that DSP itself never blocks. If Sclang blocks, OSC > messages will simply arrive late at the Server. > > Christof > On 25.10.2020 02:10, Iain Duncan wrote: > > Hi folks, I'm working on an external for Max and PD embedding the S7 > scheme interpreter. It's mostly intended to do things at event level, (algo > comp, etc) so I have been somewhat lazy around real time issues so far. But > I'd like to make sure it's as robust as it can be, and can be used for as > much as possible. Right now, I'm pretty sure I'm being a bad > real-time-coder. When the user wants to delay a function call, ie (delay > 100 foo-fun), I'm doing the following: > > - callable foo-fun gets registered in a scheme hashtable with a gensym > unique handle > - C function gets called with the handle > - C code makes a clock, storing it in a hashtable (in C) by the handle, > and passing it a struct (I call it the "clock callback info struct") with > the references it needs for it's callback > - when the clock callback fires, it gets passed a void pointer to the > clock-callback-info-struct, uses it to get the cb handle and the ref to the > external (because the callback only gets one arg), calls back into Scheme > with said handle > - Scheme gets the callback out of it's registry and executes the stashed > function > > This is working well, but.... I am both allocating and deallocating memory > in those functions: for the clock, and for the info struct I use to pass > around the reference to the external and the handle. Given that I want to > be treating this code as high priority, and having it execute as > timing-accurate as possible, I assume I should not be allocating and > freeing in those functions, because I could get blocked on the memory > calls, correct? I think I should probably have a pre-allocated pool of > clocks and their associated info structs so that when a delay call comes > in, we get one from the pool, and only do memory management if the pool is > empty. (and allow the user to set some reasonable config value of the clock > pool). I'm thinking RAM is cheap, clocks are small, people aren't likely to > have more than 1000 delay functions running concurrently or something at > once, and they can be allocated from the init routine. > > My questions: > A) Am I right, both about being bad, and about clock pre-allocation and > pooling being a decent solution? > B) Does anyone have tips on how one should implement and use said clock > pool? > > I suppose I should probably also be ensuring the Scheme hash-table doesn't > do any unplanned allocation too, but I can bug folks on the S7 mailing list > for that one... > > Thanks! > iain > > _______________________________________________ > Pd-dev mailing > [email protected]https://lists.puredata.info/listinfo/pd-dev > > > _______________________________________________ > Pd-dev mailing > [email protected]https://lists.puredata.info/listinfo/pd-dev > > _______________________________________________ > Pd-dev mailing list > [email protected] > https://lists.puredata.info/listinfo/pd-dev >
_______________________________________________ Pd-dev mailing list [email protected] https://lists.puredata.info/listinfo/pd-dev
