Created
August 30, 2017 19:11
-
-
Save mooman219/7a881b2d043354d44036e0df35d1e0b5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/////////////////////////////////////// | |
// Baseline | |
/////////////////////////////////////// | |
@Benchmark | |
public double baseline() { | |
double sum = 0; | |
for (double x = -3D; x < 3D; x += 0.001D) { | |
for (double y = -3D; y < 3D; y += 0.001D) { | |
sum += 1; | |
} | |
} | |
return sum; | |
} | |
/////////////////////////////////////// | |
// Icecore's atan2 ( http://www.java-gaming.org/topics/extremely-fast-atan2/36467/msg/346145/view.html#msg346145 ) | |
/////////////////////////////////////// | |
public static final class Icecore extends Atan2Benchmark { | |
public Icecore() { | |
super("Icecore"); | |
} | |
@Override | |
public float test(float x, float y) { | |
return Icecore.atan2(x, y); | |
} | |
private static final int Size_Ac = 1000; | |
private static final int Size_Ar = Size_Ac + 1; | |
private static final float Pi = (float) Math.PI; | |
private static final float Pi_H = Pi / 2; | |
private static final float Atan2[] = new float[Size_Ar]; | |
private static final float Atan2_PM[] = new float[Size_Ar]; | |
private static final float Atan2_MP[] = new float[Size_Ar]; | |
private static final float Atan2_MM[] = new float[Size_Ar]; | |
private static final float Atan2_R[] = new float[Size_Ar]; | |
private static final float Atan2_RPM[] = new float[Size_Ar]; | |
private static final float Atan2_RMP[] = new float[Size_Ar]; | |
private static final float Atan2_RMM[] = new float[Size_Ar]; | |
static { | |
for (int i = 0; i <= Size_Ac; i++) { | |
double d = (double) i / Size_Ac; | |
double x = 1; | |
double y = x * d; | |
float v = (float) Math.atan2(y, x); | |
Atan2[i] = v; | |
Atan2_PM[i] = Pi - v; | |
Atan2_MP[i] = -v; | |
Atan2_MM[i] = -Pi + v; | |
Atan2_R[i] = Pi_H - v; | |
Atan2_RPM[i] = Pi_H + v; | |
Atan2_RMP[i] = -Pi_H + v; | |
Atan2_RMM[i] = -Pi_H - v; | |
} | |
} | |
public static final float atan2(float y, float x) { | |
if (y < 0) { | |
if (x < 0) { | |
//(y < x) because == (-y > -x) | |
if (y < x) { | |
return Atan2_RMM[(int) (x / y * Size_Ac)]; | |
} else { | |
return Atan2_MM[(int) (y / x * Size_Ac)]; | |
} | |
} else { | |
y = -y; | |
if (y > x) { | |
return Atan2_RMP[(int) (x / y * Size_Ac)]; | |
} else { | |
return Atan2_MP[(int) (y / x * Size_Ac)]; | |
} | |
} | |
} else { | |
if (x < 0) { | |
x = -x; | |
if (y > x) { | |
return Atan2_RPM[(int) (x / y * Size_Ac)]; | |
} else { | |
return Atan2_PM[(int) (y / x * Size_Ac)]; | |
} | |
} else { | |
if (y > x) { | |
return Atan2_R[(int) (x / y * Size_Ac)]; | |
} else { | |
return Atan2[(int) (y / x * Size_Ac)]; | |
} | |
} | |
} | |
} | |
} | |
public static final class IcecoreCache extends Atan2Benchmark { | |
public IcecoreCache() { | |
super("IcecoreCache"); | |
} | |
@Override | |
public float test(float x, float y) { | |
return IcecoreCache.atan2(x, y); | |
} | |
private static final float Pi = (float) Math.PI; | |
private static final float Pi_H = Pi / 2; | |
//4 x 4000 = 16 kb L1 Cache | |
private static final int Size_Ac = 4000; | |
private static final float Atan2[]; | |
static { | |
final int Size_Ar = Size_Ac + 1; | |
Atan2 = new float[Size_Ar]; | |
for (int i = 0; i <= Size_Ac; i++) { | |
double d = (double) i / Size_Ac; | |
double x = 1; | |
double y = x * d; | |
Atan2[i] = (float) Math.atan2(y, x); | |
} | |
} | |
public static final float atan2(float y, float x) { | |
if (y < 0) { | |
if (x < 0) { | |
// (y < x) because == (-y > -x) | |
if (y < x) { | |
return -(Pi_H + Atan2[(int) (x / y * Size_Ac)]); | |
} else { | |
return Atan2[(int) (y / x * Size_Ac)] - Pi; | |
} | |
} else { | |
y = -y; | |
if (y > x) { | |
return Atan2[(int) (x / y * Size_Ac)] - Pi_H; | |
} else { | |
return -Atan2[(int) (y / x * Size_Ac)]; | |
} | |
} | |
} else { | |
if (x < 0) { | |
x = -x; | |
if (y > x) { | |
return Pi_H + Atan2[(int) (x / y * Size_Ac)]; | |
} else { | |
return Pi - Atan2[(int) (y / x * Size_Ac)]; | |
} | |
} else { | |
if (y > x) { | |
return Pi_H - Atan2[(int) (x / y * Size_Ac)]; | |
} else { | |
return Atan2[(int) (y / x * Size_Ac)]; | |
} | |
} | |
} | |
} | |
} | |
@Benchmark | |
public double atan2_icecore() { | |
float sum = 0; | |
for (float x = -3F; x < 3F; x += 0.001F) { | |
for (float y = -3F; y < 3F; y += 0.001F) { | |
sum += Icecore.atan2(x, y); | |
} | |
} | |
return sum; | |
} | |
@Benchmark | |
public double atan2_icecore_cache() { | |
float sum = 0; | |
for (float x = -3F; x < 3F; x += 0.001F) { | |
for (float y = -3F; y < 3F; y += 0.001F) { | |
sum += IcecoreCache.atan2(x, y); | |
} | |
} | |
return sum; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment