detect fma

This commit is contained in:
Zoë Gidiere
2023-10-07 22:44:19 -06:00
parent f384d09376
commit dcddc0504e
4 changed files with 45 additions and 4 deletions

View File

@@ -13,6 +13,7 @@ object Versions {
const val apacheText = "1.9"
const val apacheIO = "2.6"
const val fastutil = "8.5.6"
const val cpuFeaturesJava = "1.0.1"
}
}

View File

@@ -10,6 +10,8 @@ package com.dfsek.terra.addons.noise.samplers.noise;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
import com.google.errorprone.annotations.InlineMe;
import static com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction.PRIME_X;
import static com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction.PRIME_Y;
import static com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction.hash;
@@ -229,6 +231,7 @@ public class PseudoErosionSampler implements NoiseSampler {
this.cellularJitter = 0.43701595 * jitterModifier;
}
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
double finalDistance = Double.MAX_VALUE;
@@ -248,8 +251,8 @@ public class PseudoErosionSampler implements NoiseSampler {
int gridYi = gridY + yi;
int jitterIdx = hash(seed, gridXiPrimed, gridYi * PRIME_Y) & (255 << 1);
double cellX = Math.fma(RAND_VECS_2D[jitterIdx], cellularJitter, gridXi);
double cellY = Math.fma(RAND_VECS_2D[jitterIdx | 1], cellularJitter, gridYi);
double cellX = MathUtil.fma(RAND_VECS_2D[jitterIdx], cellularJitter, gridXi);
double cellY = MathUtil.fma(RAND_VECS_2D[jitterIdx | 1], cellularJitter, gridYi);
// Transform to actual coordinates for lookup
double actualCellX = cellX * inverseFrequency;
@@ -322,7 +325,7 @@ public class PseudoErosionSampler implements NoiseSampler {
double x2dx = x - x2;
double y2dx = y - y2;
double dotProduct = Math.fma(ldy, y1dx, (ldx * x1dx));
double dotProduct = MathUtil.fma(ldy, y1dx, (ldx * x1dx));
double lt = dotProduct * invLineLengthSquared; // Position along the line
if (lt > 0) {
@@ -330,7 +333,7 @@ public class PseudoErosionSampler implements NoiseSampler {
} else if (lt < -1) {
return MathUtil.hypot(x2dx, y2dx); // Distance between point 2 and position
} else {
double distance = Math.fma(ldy, x1dx, (-(ldx * y1dx))) * Math.sqrt(invLineLengthSquared);
double distance = MathUtil.fma(ldy, x1dx, (-(ldx * y1dx))) * Math.sqrt(invLineLengthSquared);
return Math.abs(distance); // Distance from the line
}
}

View File

@@ -8,4 +8,8 @@ dependencies {
api("com.github.ben-manes.caffeine:caffeine:3.1.0")
api("io.github.aecsocket", "cpu-features-jni", Versions.Libraries.Internal.cpuFeaturesJava)
api("io.github.aecsocket", "cpu-features-jni-natives-linux", Versions.Libraries.Internal.cpuFeaturesJava)
api("io.github.aecsocket", "cpu-features-jni-natives-windows", Versions.Libraries.Internal.cpuFeaturesJava)
api("io.github.aecsocket", "cpu-features-jni-natives-macos", Versions.Libraries.Internal.cpuFeaturesJava)
}

View File

@@ -7,6 +7,11 @@
package com.dfsek.terra.api.util;
import cpufeatures.CpuFeatures;
import cpufeatures.aarch64.Aarch64Feature;
import cpufeatures.arm.ArmFeature;
import cpufeatures.x86.X86Feature;
import java.util.List;
@@ -19,6 +24,26 @@ public final class MathUtil {
private static final double degFull, degToIndex;
private static final double[] sin, cos;
public static final boolean hasFMA;
static {
boolean configHasFMA = false;
try {
CpuFeatures.load();
configHasFMA = switch (CpuFeatures.getArchitecture()) {
case UNSUPPORTED -> false;
case AARCH64 -> CpuFeatures.getAarch64Info().has(Aarch64Feature.ASIMD);
case ARM -> CpuFeatures.getArmInfo().has(ArmFeature.NEON);
case RISCV -> true;
case X86 -> CpuFeatures.getX86Info().has(X86Feature.FMA3);
};
} catch (Throwable t) {
System.err.println("Failed to determine FMA support, assuming no FMA support");
}
hasFMA = configHasFMA;
System.out.println("FMA: " + configHasFMA);
}
static {
SIN_BITS = 12;
SIN_MASK = ~(-1 << SIN_BITS);
@@ -259,4 +284,12 @@ public final class MathUtil {
public static double hypot(double x, double y) {
return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}
public static double fma(double a, double b, double c) {
if (hasFMA) {
return Math.fma(a, b, c);
} else {
return a * b + c;
}
}
}