summaryrefslogtreecommitdiff
path: root/src/main/java/org/linaro/benchmarks/math/MathCordic.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/linaro/benchmarks/math/MathCordic.java')
-rw-r--r--src/main/java/org/linaro/benchmarks/math/MathCordic.java116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/main/java/org/linaro/benchmarks/math/MathCordic.java b/src/main/java/org/linaro/benchmarks/math/MathCordic.java
new file mode 100644
index 0000000..313e52c
--- /dev/null
+++ b/src/main/java/org/linaro/benchmarks/math/MathCordic.java
@@ -0,0 +1,116 @@
+/*
+ * Ported to java from:
+ * https://github.com/WebKit/webkit/blob/master/PerformanceTests/SunSpider/tests/sunspider-1.0.2/math-cordic.js
+ *
+ * Copyright (C) Rich Moore. All rights reserved.
+ * Copyright (C) 2015 Linaro Limited. For the port to Java
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Description: A simple and efficient algorithm used to calculate
+ * trigonometric cos and sin functions using additions,
+ * subtractions and bitshifts.
+ * Main Focus: Bitshifts, Floating-Point operations.
+ *
+ */
+
+package org.linaro.benchmarks.math;
+
+import java.lang.System;
+import org.openjdk.jmh.annotations.*;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Benchmark)
+
+public class MathCordic {
+ private static double[] ANGLES;
+ private static final double AG_CONST = 0.6072529350;
+ private static final double CORDIC_EXPECTED = 10362.570468755888;
+ private static final double RAD_CONST = 0.017453;
+ private static final double TARGET_CONST = 28.027;
+ private static final double X_CONST = 65536.0;
+
+ private static double fixedMul(double x) {
+ return x * X_CONST;
+ }
+
+ private static double fixedDiv(double x) {
+ return x / X_CONST;
+ }
+
+ private static double deg2rad(double x) {
+ return x * RAD_CONST;
+ }
+
+ static {
+ ANGLES = new double[] {
+ fixedMul(45.0), fixedMul(26.565), fixedMul(14.0362), fixedMul(7.12502),
+ fixedMul(3.57633), fixedMul(1.78991), fixedMul(0.895174), fixedMul(0.447614),
+ fixedMul(0.223811), fixedMul(0.111906), fixedMul(0.055953), fixedMul(0.027977) };
+ }
+
+ private double cordicSinCos(double target) {
+ double x;
+ double y;
+ double targetAngle;
+ double currentAngle;
+
+ x = fixedMul(AG_CONST); /* AG_CONST * cos(0) */
+ y = 0.0; /* AG_CONST * sin(0) */
+ currentAngle = 0.0;
+ targetAngle = fixedMul(target);
+
+ for (int i = 0; i < ANGLES.length; i++) {
+ double newX;
+ if (targetAngle > currentAngle) {
+ newX = x - ((long)y >> i);
+ y = ((long)x >> i) + y;
+ x = newX;
+ currentAngle += ANGLES[i];
+ } else {
+ newX = x + ((long)y >> i);
+ y = -((long)x >> i) + y;
+ x = newX;
+ currentAngle -= ANGLES[i];
+ }
+ }
+
+ return fixedDiv(x) * fixedDiv(y);
+ }
+
+ @Benchmark
+ public double jmhTimeMathCordic() {
+ // When profiling, hot region is in jmhTimeMathCordic_avgt_jmhStub not jmhTimeMathCordic.
+ // This may be caused by inlining jmhTimeMathCordic in jmhTimeMathCordic_avgt_jmhStub.
+ // The following "loops" is added to work around this problem.
+ int loops = 400;
+ double s = 0;
+ for (int i = 0; i < loops; i++) {
+ s += cordicSinCos(TARGET_CONST);
+ }
+ return s;
+ }
+}