Hacker News new | ask | show | jobs
by ssfrr 2784 days ago
Looks super slick, thanks for sharing!

Can you give a little more detail in how this compares architecturally with something like PD? I imagine a tradeoff of generating LLVM MIR and compiling it is that you can get better performance, but don't get the interactive experience of hearing changes immediately as you tweak the object graph.

Does the DSP graph operate on blocks or sample-by-sample?

1 comments

I haven't actually properly played around with PureData (other than watching a few videos on it back when I started this project), so I can't really comment too much on how that compares.

I was initially worried about how interactive compiling would be, however it turns out (at least with the projects we've tested it with so far), it's pretty easily able to keep up with around 3ms from a modification to codegen being complete. The LLVM IR we generate is pretty simple which helps, and we also try to only recompile as much as possible by putting everything in separate LLVM modules (hurts runtime performance a bit since we can't optimize across modules, but it doesn't end up mattering too much).

The graph operates per sample - we really needed that feature to be able to do feedback loops, for things like FM synthesis.

Edit: I started adding in an explanation of Axioms architecture in the hope that someone with knowledge of similar projects could chime in, but it was getting quite long... might look at writing a blog post on it sometime soon, if people would find that interesting.

Thanks for replying, I'd definitely be interested in more architectural details.

3ms to complete codegen is orders of magnitude faster than I expected. Does that include everything necessary from making the change through actually synthesizing samples?

I'll look at writing that blog post soon then :)

Just did some proper testing on a reasonably complex project, looks like I was about an order of magnitude off (to be fair it was 2AM here at the time, and I wasn't reading the numbers right haha). 30-40ms is still fast enough that you don't notice for the most part though. For this specific project, it breaks down roughly like this:

- ~1ms to build the new MIR based on the editor state

- ~5ms to process/run passes on the MIR (this involves some funky graph traversal which could very likely be optimized a lot)

- ~12ms to generate LLVM IR

- ~14ms in the LLVM JIT

In a project that makes good use of groups (nodes that contain a surface inside and then expose some controls back out) I'd expect this to be lower, since we only need to perform those operations on the surfaces that change.

Hm, 12ms for the IR is longer than I would expect for such a translation step. Do you know whwre this time is being spent?
Just had a look, and it turns out that's including running LLVM's optimizer as well, which takes roughly half the time. It's basically doing the equivalent of -O2 currently. That's probably more aggressive than what's needed, but I haven't taken the time to fine-tune it yet.

Other than that, you're right that it might be a bit high. There's very likely parts of the lowering code which can be optimized, I just haven't had the need to yet.