<div dir="ltr"><div><div><div><div>Hi Miller,<br><br></div>My intention is to write Pd code in such a way that it is maximally efficient for tiny computers which aren't fond of doubles (RPi and friends), while keeping the option open to compile with maximum precision for fast machines.<br>
<br></div>The advent of RPi has prompted me to focus more on efficiency, even though I rarely use a Pi myself. Reckoning with ARM, I guess we're sort of back in the days of Pentium 2 when it comes to precious clock cycles (but I didn't program C at that time). <br>
<br>Overlooked precision conversions happen so easily. Here is an example from tabread4~ in d_array.c: <br><br> *out++ = b + frac * (<br> cminusb - 0.1666667f * (1.-frac) * (<br> (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)<br>
)<br> );<br><br><div id="l445" class="">
</div>All literals have float suffixes, except in (1.-frac). So here is a double which makes the compiler do the first half of the interpolation routine on the FPU with extended precision (on Linux i386).<br><br></div>A few years ago I wouldn't have noticed it, and my own code my be full of unspecified literals. That's what I want to repair now. Not by adding the regular float specifier 'f' though, since that would defy the purpose of Pd's own float type definition.<br>
<br></div>Katja<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Feb 11, 2014 at 6:39 AM, Miller Puckette <span dir="ltr"><<a href="mailto:msp@ucsd.edu" target="_blank">msp@ucsd.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Katya -<br>
<br>
I think there's no simpler way. On the other hand, for constants like<br>
0.125 and 2, it would be equivalent to say 0.125f, etc - but for other<br>
constants (1/3 for example), casting as t_float would be more accurate in<br>
case t_float is set to double. I think people rarely use t_float as higher<br>
precision than 32 bits though, and even if they did the difference between<br>
(t_float)1/(t_float)3 and 1.f/3.f is pretty small.<br>
<br>
cheers<br>
Miller<br>
<div><div class="h5"><br>
On Mon, Feb 10, 2014 at 10:53:02PM +0100, katja wrote:<br>
> Hello,<br>
><br>
> When working on parabolic interpolation in a Pd class, I wondered again<br>
> what is the best method to specify literal constants as Pd's type t_float<br>
> (which could be float or double). The interpolation goes like:<br>
><br>
> ...<br>
> t_float a = buf[peakindex-1];<br>
> t_float b = buf[peakindex];<br>
> t_float c = buf[peakindex+1];<br>
> t_float realpeak;<br>
><br>
> realpeak = b + 0.125 * (c - a) * (c - a) / (2. * b - a - c);<br>
> ...<br>
><br>
> Without float suffixes for the literals, single precision t_float variables<br>
> would be promoted to double here, which would be an unintended waste of CPU<br>
> cycles. For some time, I've worked around this by using const variables<br>
> instead of literals, like:<br>
><br>
> ...<br>
> const t_float two = 2.;<br>
> const t_float eighth = 0.125;<br>
> t_float a = buf[peakindex-1];<br>
> t_float b = buf[peakindex];<br>
> t_float c = buf[peakindex+1];<br>
> t_float realpeak;<br>
><br>
> realpeak = b + eighth * (c - a) * (c - a) / (two * b - a - c);<br>
> ...<br>
><br>
> While this avoids redundant type conversions, it clutters the code and does<br>
> not result in such fast instructions as literals do. Therefore I am now<br>
> using type casts where type specifiers are normally used:<br>
><br>
> ...<br>
> t_float a = buf[peakindex-1];<br>
> t_float b = buf[peakindex];<br>
> t_float c = buf[peakindex+1];<br>
> t_float realpeak;<br>
><br>
> realpeak = b + (t_float)0.125 * (c - a) * (c - a) / ((t_float)2. * b -<br>
> a - c);<br>
> ...<br>
><br>
> For the above code I have checked assembly output as generated by GCC with<br>
> -O3 optimization on Linux i386. Using literals without type specification,<br>
> the whole routine is done on the FPU (80 bits precision). With the literals<br>
> cast to t_float, it is done with single precision instructions for XMM<br>
> registers.<br>
><br>
> As far as I can see, casting literals to t_float results in the same<br>
> assembly output as using the float specifier. For single precision<br>
> t_float, '(t_float)0.125' is equivalent to '0.125f'. I can't think of a<br>
> disadvantage, but let me know if I overlooked something.<br>
><br>
> Katja<br>
<br>
</div></div>> _______________________________________________<br>
> <a href="mailto:Pd-list@iem.at">Pd-list@iem.at</a> mailing list<br>
> UNSUBSCRIBE and account-management -> <a href="http://lists.puredata.info/listinfo/pd-list" target="_blank">http://lists.puredata.info/listinfo/pd-list</a><br>
<br>
</blockquote></div><br></div>