Performance Tips: floating-point mod

Recently I implemented in Vult a simpler way for me to measure the performance of the generated code. Running the command $ make perf generates code for all languages and runs it for most of the examples.

The results are displayed in ms/s (milliseconds taken to render one second of audio). For most of the examples the C++ with fixed-point is the fastest. In a few instances is slower than C++ with floating point. I’m still investigating these cases. LuaJIT is slightly slower than C++ and then comes JavaScript.

When rendering the different implementations of Saw wave oscillators we get the following result (MacBook Air with 1,4 GHz Intel Core i5):

A few strange things can be spotted by looking at the table. The Saw PRT gets almost twice as slow for Js. I’m not gonna investigate that one here. The one that is more interesting is the Saw R? going from fixed-point to floating-point; it gets 3 to 4 times slower.

The implementation (part of it) looks as follows:

After playing a bit I found the problem. The line mem phase = (2.0 * inc + phase) % 2.0; uses the mod operation on a floating-point number in order to wrap the phase. When this is converted to fixed-point (integers) the mod operation is performed on integers which is much faster than on floating-point.

By changing that line to the following lines:

we avoid calling fmod which seems to be more expensive. This will make the fixed-point a little bit slower, but the floating-point becomes faster. The updated table after performing the change is as follows:

Conclusion

Avoid using % (mod on floats) unless is strictly necessary.

Used Band Limited Algorithms

EPTR : Efficient Polynomial Transition Regions

PTR : Polynomial Transition Regions

BLIT : Band-Limited Impulse Train

R? : I don’t know the name of this algorithm

Among these algorithms, the only one that produces real band-limited waveforms is the BLIT.