Small or fast?
Life is often about compromise, but embedded developers really are not good at that. Code generation is a context in which compromise is somewhat inevitable and we call it “optimization”. All modern compilers perform optimization, of course. Some do a better job than others. A lot of the time, the compiler simply guesses which optimization will produce the best result without knowing what the designer really wants. For desktop applications, this is OK. Speed is the only important criterion, as memory is effectively free. But embedded is different …
To the first approximation, all desktop computers are the same. It is quite straightforward to write acceptable applications that will run on anyone’s machine. Also, the broad expectations of their users are the same. Embedded systems are all different – the hardware and software environment varies widely and the expectations of users are just as diverse. In many ways, this is what is particularly interesting about embedded software development.
An embedded compiler is likely to have a great many options to control optimization. Sometimes that fine-grain control is vital; on other occasions, it can come down to a simple choice between optimization for speed or size. This choice is curious, but it is simply an empirical observation that small code is often slower and fast code tends to need more memory.
An obvious example is function inlining. A small function can be optimized so that its actual code is place in line at each call site. This executes faster because the call/return sequence is eliminated. But it will use more memory as there may be multiple copies of identical code. Sometimes you can get lucky and an optimization which yields faster code is also light on memory, but this is quite unusual.
The control of optimization for embedded code generation is not set to get any easier, as more possibilities are coming along. Notably, there is increased interest in minimizing power consumption. An algorithm may be selected on the basis of how much CPU power it requires to get the job done. This is subtle, because fast code needs less CPU power, but smaller code needs less memory, which consumes power.
I would be very interested to hear your stories by comment or email about good [and bad] optimizations that you have encountered.
Posted January 11th, 2010, by Colin Walls