Optimizing code generated by SpinCAD

Digital Larry

Active member
Among more elite crowds, over the tinkling of glasses of chardonnay, one can occasionally discern such statements as: "SpinCAD generates such terribly inefficient code!" accompanied by clutching of pearls and so on.

I wasn't even planning on working on this, but you know how that goes. Anyway, it looks promising in that:
a) I have figured out a way to scan the generated code looking for patterns which can be optimized.
b) I have come up with the lowest hanging fruit in this area, which is to get rid of the extra instruction that is often used to join two blocks together.

1712263141238.png
On the left, you see pre-optimized code. The code of yesteryear, one might say. And on the right, you see that 4 instructions have been saved in a very small program. So, this is likely to help most when you have a lot of blocks. And it will help mostly when the blocks are all in a row. And it will help more when the blocks have their input pin as the first instruction. Like in this design:

1712263325197.png
I should remind you that NOT ALL BLOCKS have their input as the very first instruction. But many do!

I'm going to hammer on this a bit more and then make a beta available to see if anyone can break it.

There are other patterns which I can work on later, some of which are described here: https://holy-city-audio.gitbook.io/...1-assembly-code-generated-by-spincad-designer

DL
 
Before everyone gets too excited, the example I showed skews towards over-representing its capability. You really don't get much of anything from optimization until you are going over the 128 instruction limit. I tried a few different large designs and got from 2 to 5 instructions saved. Rather than blather on about it here, I'll simply say that it's a work in progress and this is just the beginning. Keeps my mind active.

It sounds like some of you are former, possibly current, or recovering SW/IT people. So for those of you who want to get a peek at "how it's done", here's a link to the freshly written optimizer routine. The 128 possible instructions rendered from the GUI model are assembled as a linked list, so we can scan through it, find things (specific instructions, references to certain registers, etc.), look for other things that match, forwards, backwards, build up a new list using different criteria, etc. Brain fun for years!

The thing that is really interesting is that you can look at the code and say, "oh this section needs to move down here between these two instructions". Trying to figure out what that really means in Java is quite the challenge. Towers of Hanoi? Reminds me of that.

I think I'm going to try for one more strategy before I push out a beta. The way I'm approaching it, optimization steps are cumulative rather than all having to be done at once. I've never really written anything like this so it will be interesting.

In fact, this IS an open-source project (cough cough). Anyone want to help write the SpinCAD optimizer? I mean the accompanying social advantages alone are, well, hard to imagine. :ROFLMAO:

 
Last edited:
That's all very exciting, Thanks Larry!! Imo the only thing on top of this, that would be helpful is to have the actual number of instructions after you exceeded the 128 instructions so we can be aware later if this patch is going to make it to 128 inst after optimizing or not
 
That's all very exciting, Thanks Larry!! Imo the only thing on top of this, that would be helpful is to have the actual number of instructions after you exceeded the 128 instructions so we can be aware later if this patch is going to make it to 128 inst after optimizing or not
Hi Ted, well I had considered somehow displaying how "awesome" the optimizer is, but the flip side of that perspective is that it would just be pointing out the shortcomings of SpinCAD. So it's thrilling for me after all these years to have an approach, but I don't think anyone else cares as long as it works. I'd just display the end result rather than before/after. The most optimizable patch is apparently as shown, a long single chain of 1 pole low pass and high pass filters. Unfortunately, that is fairly useless.

TL;DR section

While I'm thinking about it, the next thing that needs to happen is to arrange the code fragments so that strategy #1 can work. Rendered blocks in SpinCAD are separated from the previous one by the fact that the accumulator has been set to zero. e.g. WRAX REG15,0 Any time that happens, we can start doing something else - and we can move those something elses around providing we don't move something towards the front and read something before it was written, for example. This approach even subdivides blocks if they have multiple outputs as there can be more than one WRAX REGx,0.

The way SpinCAD works is to allocate registers to blocks in such a way that they only share references to registers on their inputs and outputs. Within a block registers are allocated incrementally in the order that they are encountered.

Multiple parallel short chains of blocks (e.g. feeding into a 4:1 mixer) are apparently not sorted so that all the rendered code sections in the shorter chains are next to each other. They are interleaved like shuffling cards. So the goal is to move all code blocks to be adjacent to each other IF they share that register in such a way that it can be optimized out. Since a register (block output) can fan out to multiple destinations, obviously only one such optimization can take place per register. And furthermore blah blah blah.

DL
 
Last edited:
Back
Top