Hello,
When working on parabolic interpolation in a Pd class, I wondered again
what is the best method to specify literal constants as Pd's type t_float
(which could be float or double). The interpolation goes like:
...
t_float a = buf[peakindex-1];
t_float b = buf[peakindex];
t_float c = buf[peakindex+1];
t_float realpeak;
realpeak = b + 0.125 * (c - a) * (c - a) / (2. * b - a - c);
...
Without float suffixes for the literals, single precision t_float variables
would be promoted to double here, which would be an unintended waste of CPU
cycles. For some time, I've worked around this by using const variables
instead of literals, like:
...
const t_float two = 2.;
const t_float eighth = 0.125;
t_float a = buf[peakindex-1];
t_float b = buf[peakindex];
t_float c = buf[peakindex+1];
t_float realpeak;
realpeak = b + eighth * (c - a) * (c - a) / (two * b - a - c);
...
While this avoids redundant type conversions, it clutters the code and does
not result in such fast instructions as literals do. Therefore I am now
using type casts where type specifiers are normally used:
...
t_float a = buf[peakindex-1];
t_float b = buf[peakindex];
t_float c = buf[peakindex+1];
t_float realpeak;
realpeak = b + (t_float)0.125 * (c - a) * (c - a) / ((t_float)2. * b -
a - c);
...
For the above code I have checked assembly output as generated by GCC with
-O3 optimization on Linux i386. Using literals without type specification,
the whole routine is done on the FPU (80 bits precision). With the literals
cast to t_float, it is done with single precision instructions for XMM
registers.
As far as I can see, casting literals to t_float results in the same
assembly output as using the float specifier. For single precision
t_float, '(t_float)0.125' is equivalent to '0.125f'. I can't think of a
disadvantage, but let me know if I overlooked something.
Katja