6 ms·
To be flexible without if / else or switches. If i want a multi-oscillator that can produce different waveforms i use a pointer to different functions depending
by iammyIP 10y ago
To be flexible without if / else or switches. If i want a multi-oscillator that can produce different waveforms i use a pointer to different functions depending on the waveform i need. Same goes for different postprocessing / routing. I didn't actually profile this compared to a switch, but for me it's cleaner and more modular. If you got a static effect whose routing stays the same you don't need it of course.
edit: i've never used a virtual method, but my impression is that performance-wise it's quite different to pointers to simple functions. most of my audio code is pod-structs to layout the data in the order that it gets acessed and standalone functions that then modify stuff in the structs.
it's pretty barebones data oriented programming compared to the other extreme, some baroque meta virtualised oop architecture.
- vardump 10y agoRuntime codegen could make a big difference. You can dynamically build your processing pipes without overhead. No function pointers needed, total flexibility. Check JIT libraries (like GNU lightning) and LLVM. Also LuaJIT might be interesting. "llvmpipe", software rasterizer that uses LLVM for runtime codegen for shaders: http://www.mesa3d.org/llvmpipe.html http://www.mesa3d.org/llvmpipe.html
- iammyIP 10y agosounds intriguing and way more flexible, but the example is for video? i don't know anything about this, but if i had to guess i would say that any runtime code generation is worse performance wise compared to a mix of pod structs and function pointers to functions which are all known at compile time.
- vardump 10y ago> runtime code generation is worse performance wise compared to a mix of pod structs and function pointers to functions which are all known at compile time Having "a mix of pod structs and function pointers" is analogous to having an interpreter for some scripting language. Do you consider interpreted scripting languages fast? Interpreters are slow pretty much for that reason. Having to chase pointers. Runtime code generating JITs wipe floor with interpreters, being usually 10-100x faster. Now I'm not saying your application will be 10-100x faster, but done right, it'll absolutely be faster if your performance critical "inner loop" / filter chain needs to currently follow pointers. It's just a question of how much and whether it matters for the use case.
- iammyIP 10y ago[Having "a mix of pod structs and function pointers" is analogous to having an interpreter for some scripting language.] Yes, it might be similar at the core, but i would guess the usual audio pod-struct/function mix is many times less complex than a full jit language interpreter. What does chasing pointer mean to slowness then? My understanding is that its similar to data pointers, that a certain region of memory needs to be looked up and be fed into the instruction cache. If the process is layed out so that instruction cache misses are minimised, whats so bad about it?
- vardump 10y ago> whats so bad about it? Other than executing a lot of useless instructions, causing pipeline stalls due to indirection, potentially mispredicted branches, etc. I guess nothing. Just remember if the actual operation is just a few instructions, the price for all that extra work can be 1-2 orders of magnitude. If you only need to chase pointers say a million times per second or less, go for it. It won't matter so much. In worst cases you might lose 10% (of total cpu core capacity) performance, if even that. If it's in tens of millions or more, it's pretty likely to be a significant bottleneck. What does your profiler say? What kind of ILP you're getting?
- iammyIP 10y agoThe current code with the function pointers and pods works ok for me, its about in the million per second range and i didn't profile any alternative to it. How would you implement such an alternative with jit code generation into this pod/function c code setup without major rewrites? Seems to me like a completely different system which is bound to llvm (i use gcc)? edit: since you were mentioning jit optimisation and code generation - this is a field i do not have any experience, but my impression so far is that this runtime re-arrangement of code can yield quite a big performance increase for higher level languages (jvm does this afaik). Is the link you provided the same idea for statically compiled c/c++ code?
- vardump 10y ago
- jvoorhis 10y agoIts ancient now, but I built exactly this using Ruby and an LLVM wrapper. https://github.com/jvoorhis/siren https://github.com/jvoorhis/siren I wouldn't expect this to run on the latest LLVM without a little hand holding (the most painful part was porting it to run on x86_64 after developing it on my white MacBook!) But it worked rather well and was a fun platform for experimenting with composition, synthesis and compilers!