Hi Will,
while I'm currently investigating in detail how GUI components are launched,
I'd like to share some observations and thoughts. One question is about
how far we want / reasonably should drive that new system?
We started this development under the impression that there are some
exceptional cases where the GUI grabs into the core to access some
larger data tables. Most other communication with the GUI would still
work by individual data propagation through the command ringbuffers.
While looking into the SubSynth yesterday, it occurred to me that
/in theory/ we could switch the complete GUI to bulk updates, always
triggered at that point when the Synth detects a "parameters changed".
This would of course be a much more drastic change, and also has
some trade-offs, which we are far from being able to judge adequately.
However, just wanted to point out that theoretical possibility.
Another aspect is also related to trade-offs.
It seems indicated to point out that the way Yoshimi handles the
data connection currently is probably the /most performant way/ possible.
It has some other downsides and it might be in danger of data-races
on occasion -- but any other system, which does *not* directly read
core data, is probably slower, has more latency, and requires us
to set aside some buffer memory.
I know that we were also motivated to try out this changed GUI connection
in an attempt to clean up the structures in the code, which are still
somewhat complicated and hard to understand. Just we should be aware
that this change has a price tag. Our initial guess was that this
additional overhead is not really prohibitive, since the GUI runs
comparatively slow, and memory is abundant.
Speaking of memory: with the new system, we have to pick suitable
parameters for the data buffer and the number of slots to reserve.
My current (initial) implementation is deliberately rather simplistic,
which means, we use a single slot size for all exchanges, and a fixed
pre-allocated number of slots. This means, the largest data type we
want to transport will dictate the overall amount of memory we have
to reserve for the new system.
Looking at InterChange.h, I see that the "toGUI" ringbuffer uses
a size of 2048 slots. Obviously, there is much more communication
going over /that/ channel. Yet non the less, we're faced with the
question how much slots we should reserve for the new system.
Of course, this largely depends on how we use it. Basically we
must set aside enough slots to accommodate for all data publish
events, which happen until the GUI wakes up again, clears the
slots and dispatches the data. As we know, this duty-cycle
of the GUI is in the order of magnitude of 33ms.
Needless to say, we could improve the situation by making the
system more dynamic. For example, we could add the ability for
the data buffer just to grow on demand. This is very much doable,
but also more complicated (which means more possible errors and
more sources for possible performance problems). For that reason
I'd rather not engage into such a dynamic mechanism without having
tried the more simple solution first.
-- Hermann
_______________________________________________
Yoshimi-devel mailing list
Yoshimi-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/yoshimi-devel