@Riven: Showing code that runs faster in float vs. double is easy.
On: Early P4, Last P4, Core Duo (2 core), Core Duo (4 core) - Sun JRE 1.6.0_13-b03:
sin core is between 1.5-1.8 times faster in float.
ortho polynomial is between 1.2-1.5 time faster.
public class Foo
{
public static float approxF(float x)
{
float x2, r;
x2 = x*x;
r = -2.39e-08f;
r *= x2;
r += 2.7526e-06f;
r *= x2;
r -= 1.98409e-04f;
r *= x2;
r += 8.3333315e-03f;
r *= x2;
r -= 1.666666664e-01f;
r *= x2;
r += 1.f;
r *= x;
return r;
}
public static double approxD(double x)
{
double x2, r;
x2 = x*x;
r = -2.39e-08f;
r *= x2;
r += 2.7526e-06f;
r *= x2;
r -= 1.98409e-04f;
r *= x2;
r += 8.3333315e-03f;
r *= x2;
r -= 1.666666664e-01f;
r *= x2;
r += 1.f;
r *= x;
return r;
}
public static double evalD(int n, double x)
{
double r = 1;
double a = 1;
double b = x;
int i;
if (n >= 2) {
for (i = 2; i <= n; i++) {
r = ((2 * i - 1) * x * b - (i - 1) * a) / i;
a = b;
b = r;
}
return r;
}
if (n == 0)
return a;
return b;
}
public static float evalF(int n, float x)
{
float r = 1;
float a = 1;
float b = x;
int i;
if (n >= 2) {
for (i = 2; i <= n; i++) {
r = ((2 * i - 1) * x * b - (i - 1) * a) / i;
a = b;
b = r;
}
return r;
}
if (n == 0)
return a;
return b;
}
public static void main(String[] args)
{
double x = 1.5707;
int i;
try {
if (args.length != 0)
x = Double.parseDouble(args[0]);
}
catch(Exception e) {}
float f = approxF((float)x);
double d = approxD(x);
int e = 100000;
long t0 = System.nanoTime();
for(i=0; i<e; i++)
d = approxD(d);
long t1 = System.nanoTime();
for(i=0; i<e; i++)
f = approxF(f);
long t2 = System.nanoTime();
t0 = t1-t0;
t1 = t2-t1;
System.out.printf("double = %d (x %f)\n", t0, (1.f*t0)/t1);
System.out.printf("float = %d\n", t1);
e = 20000;
d = evalD(10, d);
f = evalF(10, f);
t0 = System.nanoTime();
for(i=10; i<e; i++)
d += evalD(i, .332);
t1 = System.nanoTime();
for(i=10; i<e; i++)
f += evalF(i, .332f);
t2 = System.nanoTime();
t0 = t1-t0;
t1 = t2-t1;
System.out.printf("double = %d (x %f)\n", t0, 1.0*t0/t1);
System.out.printf("float = %d\n", t1);
System.out.printf("%f\n", f);
System.out.printf("%f\n", d);
}
}
@DzzD: I started programming in the 8-bit days, but that isn’t my problem. I use doubles and multi-precision elements all the time…when needed.
There are three important trends that form my opinion about doubles being unlikely to outperform floats on consumer hardware in my lifetime. The first two have already been mentioned: SIMD and speed gap with main memory. The other is die size reductions. Making the channels narrower requires increased energy consumption (and therefore heat). Thus it is becoming more and more important to shut down subsystems which are not in usage to reduce heat (and battery drain in the case of notebooks). Computation of doubles requires wider data paths and more stages (to slightly vuglarize).
In real life I do a fair amount of low level and optimization work so I read a fair number of CPU design specs and semi-keep up with hardware design research and am seeing nothing to contradict this opinon. However I’ll admit that I never expected to see anything like the new decimal formats from IEEE 754-2008 either.