[CM] S7s GC

Iain Duncan iainduncanlists at gmail.com
Mon Nov 23 06:44:53 PST 2020

Thanks very much Bill and Kjetil. Sounds like there is a lot to learn here.
The thing that is confusing me right now is why it hasn't been a problem so
far in my timing tests of scheduling. Hopefully you don't mind
another barrage of questions.

Some background, basically I have two kinds of work going on: timing
critical (notes and control events playing) and general i/o that is not
critical (user moving dials, updating sequences, what have you). Right now
I'm trying to make sure there are good options for users to pick their
tradeoffs. Bizarrely, i've not noticed any delays from the GC running. I'm
wondering if this is because the delay/schedule code works by having the
max scheduler trigger it and that the GC never runs between wake up time
and completion of those functions (which are pretty light). I think for my
purposes, sub 5ms jitter is something we can live with, though i don't seem
to even be getting that so far, but nor have I pushed it. This is really
"event" real time, not audio real time. I'm going to call the pass at the
interpreter that is run from the scheduler the "event pass" for
nomenclature's sake..

1) So if it traces live objects, does that mean minimizing the object tree
in an instance will cut down the time it takes to run the GC? and is there
any advantage to certain kinds of objects? As in, does it speed up the GC
pass if I'm using top level globals and simply calling set on them so that
there is not much for the GC to trace? Or any other code level strategies
to speed up the GC pass?

2) I could just turn off the GC for these event passes. But I'm not clear
how I let it run again as Bill said it can't be manually triggered (I do
think that would be super helpful if you get that itch though Bill! :-) )
Do I need to run some scheme code with the GC back on and it will just
happen? I would be totally fine with allocating a big heap and deferring
the pass while "deliberating leaking" for a while. I was under the
impression nothing happens in S7 until C makes a call, but am I wrong
there? Does the GC sometimes just do it's thing from a thread?

3) I have been confused about threading in S7. It seems to me that it works
fine for me to access the same S7 interp from multiple threads, but am I
just getting lucky? I cooked up the option to lock the s4m object into 1
thread because I thought that at some point I was going to get data
structure corruption if I have two different max threads making calls into
the same interpreter. But am I wrong there? If it's actually safe (or I can
make it safe somehow) for the multiple threads to call into the GC, would
it work for me turn off the GC for all events in the high thread (triggered
by midi input, clocks, or scheduler callback) and then let it run from a
call to the low thread? In max there is an option to make a low-priority
callback too, so I could perhaps use that to get the GC to run when I want
it, in the lower thread only, preserving the critical timing.

Thanks everyone!

On Mon, Nov 23, 2020 at 5:57 AM <bil at ccrma.stanford.edu> wrote:

> I forgot to say that I tried using separate threads for
> the gc (it is a natural for this in that the most
> compute-time expensive part is just spinning through
> the heap -- it can easily be split into N threads).
> But I got no speed up overall from this -- there's
> a brief comment in s7.c about it ca line 7079.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cm-mail.stanford.edu/pipermail/cmdist/attachments/20201123/ca3af2f8/attachment.html>

More information about the Cmdist mailing list