Skip to content

Instantly share code, notes, and snippets.

@mooman219
Created August 30, 2017 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mooman219/7a881b2d043354d44036e0df35d1e0b5 to your computer and use it in GitHub Desktop.
Save mooman219/7a881b2d043354d44036e0df35d1e0b5 to your computer and use it in GitHub Desktop.
///////////////////////////////////////
// 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