[music-dsp] C++ performance
rossb-lists at audiomulch.com
Sat Oct 30 02:56:08 EDT 2010
[oops hit send too soon, please ignore previous garbled reply]
> There's clarity, and there's transparency.
Agreed.. both are important: (1) clarity for understanding what the code
expresses in the problem domain (signal processing) -- since you need to be
able to look at the code and understand what kind of processing it's doing,
and (2) transparency for understanding what the CPU is doing so you can
optimise (whether by micro-optimising or going with a completely different
implementation). (2) is not so important if you are using someone elses
library and it is known to be well written and reliable (Michael's example
is Eigen but you could pick any other library).
But I think there is going to be a trade off when dealing with any
application domain/implementation domain translation:
Expressing a quicksort algorithm clearly and transparently in C++ or C is
not so hard -- quicksort is a sequential algorithm -- programming languages
are intended to express sequential algorithms. The application and
implementation domains are closely aligned.
Expressing a signal processing structure (some kind of signal flow model for
example) or perhaps some matrix algebra in C++ or C is not really likely to
be all that clear if you also want to be transparent. The more you try to be
clear, the more you will move towards a domain specific
langauge/representation, and the less transparent things will be. The more
transparent you try to be, the more your code will look like loops and
function calls and the less like something that reads as a signal processing
structure (or algebraic expression).
This trade off exists in any language. It's just that C++ gives you more
tools than C to move towards the clarity end of the scale for some domains.
I think matrix algebra is a good example: using Eigen (or Blitz or whatever)
lets you write matrix algebra in C++ using algebraic expressions rather than
matrix operation function calls as you would need to do in C. But in the
case of a lot of audio DSP.. it's less clear that there's so much benefit to
trying to construct a domain specific language in C++ -- DSP algorithms are
not always expressed using algebraic expressions: they're often expressed
using data flow structures - and translating these structures into text is
rarely particularly clear and usually involves some kind of restriction on
the domain of expressible things (think about what is hard to express in
CSound for example). Based on this, I have concluded, after thinking and
experimenting with this for a long time, that it's better to err on the side
of transparency when it comes to writing DSP code in C++> But that's not to
say you can't get some clarity benefits from using C++ over C.
One of the questions the OP asked was about efficiency of inlining when
creating abstractions with classes -- they are trying to create clearer code
by using C++'s abstraction mechanisms. They were comfortable trading off a
bit of transparency for clarity. I think most people using C++ will do this
to some degree. The further you go, the more risky it becomes -- things can
get so opaque that you have little hope of understanding the library you're
using without a lot of study (template metaprogramming systems like blitz
come to mind). But if you know they are fast, and you trust them, they can
help you write clearer code that is also efficient. (see also below).
My advice to a beginner would be to not get too carried away with
over-abstracting things for the sake of clarity. Sooner or later you will
become interested in the instructions the CPU is executing as much as the
DSP structure the code is expressing.
> In C++ I can easily read a
> piece of code and *think* I know what it does and how long it'll take
> to do it - but *only* if I trust the guy who wrote all those operator
> overloads not to have (a) dropped the ball in efficiency terms, (b)
> not to have redefined those operators in an interesting way. In C,
> reading a bunch of function calls might challenge my patience, but (a)
> that's what comments are for, isn't it? and (b) I know *exactly* how
> much each of those native constructs is going to cost me; I'm not
> going to be taken by surprise.
If you know C++ well, and the code has been written by yourself, or a
developer you trust, it probably won't have either of the problems you
describe. And it's not like C++ is some arcane language with lots of barely
competent software engineers using it (like eg Perl) -- there is really no
excuse for people not learning C++ properly if they want to use it -- there
are plenty of resources to learn C++ best practices (Herb Sutter's excellent
GoTW posts and books come to mind: http://www.gotw.ca/gotw/).
On the other hand, the learning curve to mastery is indeed long.
More information about the music-dsp