aboutsummaryrefslogtreecommitdiff
path: root/benchmarks
diff options
context:
space:
mode:
authorScott Wakeling <scott.wakeling@linaro.org>2015-11-23 14:12:32 +0000
committerScott Wakeling <scott.wakeling@linaro.org>2015-11-24 15:33:44 +0000
commite816f850d3f602191c3c5e7eb458be6c1650fac7 (patch)
tree3160593d437adae394a7ca2bca6bb8ffadd2ce60 /benchmarks
parent058c5f2d40e95f506953e369b4ea3f52e255c5af (diff)
downloadart-testing-e816f850d3f602191c3c5e7eb458be6c1650fac7.tar.gz
Add a benchmark for bitfield rotate optimizations.
Change-Id: I97f00ad32d587f130d5b2fb42420285230448954
Diffstat (limited to 'benchmarks')
-rw-r--r--benchmarks/micro/BitfieldRotate.java346
1 files changed, 346 insertions, 0 deletions
diff --git a/benchmarks/micro/BitfieldRotate.java b/benchmarks/micro/BitfieldRotate.java
new file mode 100644
index 0000000..c853c95
--- /dev/null
+++ b/benchmarks/micro/BitfieldRotate.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2000-2015 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
+ *
+ * Modifications copyright (c) 2015 Linaro Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Description: Check for regressions effecting Bouncy Castle SHA1Digest processing.
+ * Main Focus: Bitfield rotations.
+ * Secondary Focus: Loop optimizations.
+ */
+
+package benchmarks.micro;
+
+import java.nio.ByteBuffer;
+
+public class BitfieldRotate {
+ private static final String SOURCE_Text = "That though I loved them for their faults\n" +
+ "As much as for their good,\n" +
+ "My friends were enemies on stilts\n" +
+ "With their heads in a cunning cloud.\n";
+
+ private int h1;
+ private int h2;
+ private int h3;
+ private int h4;
+ private int h5;
+ private int x[] = new int[80];
+ private int xOff;
+
+ //
+ // Additive constants
+ //
+ private static final int y1 = 0x5a827999;
+ private static final int y2 = 0x6ed9eba1;
+ private static final int y3 = 0x8f1bbcdc;
+ private static final int y4 = 0xca62c1d6;
+
+ private int ffunc(
+ int u,
+ int v,
+ int w) {
+ return ((u & v) | ((~u) & w));
+ }
+
+ private int hfunc(
+ int u,
+ int v,
+ int w) {
+ return (u ^ v ^ w);
+ }
+
+ private int gfunc(
+ int u,
+ int v,
+ int w) {
+ return ((u & v) | (u & w) | (v & w));
+ }
+
+ protected void processBlock() {
+ //
+ // expand 16 word block into 80 word block.
+ //
+ for (int i = 16; i < 80; i++) {
+ int t = x[i - 3] ^ x[i - 8] ^ x[i - 14] ^ x[i - 16];
+ x[i] = t << 1 | t >>> 31;
+ }
+
+ //
+ // set up working variables.
+ //
+ int a = h1;
+ int b = h2;
+ int c = h3;
+ int d = h4;
+ int e = h5;
+
+ //
+ // round 1
+ //
+ int idx = 0;
+
+ for (int j = 0; j < 4; j++) {
+ // E = rotateLeft(a, 5) + ffunc(b, c, d) + E + x[idx++] + y1
+ // B = rotateLeft(b, 30)
+ e += (a << 5 | a >>> 27) + ffunc(b, c, d) + x[idx++] + y1;
+ b = b << 30 | b >>> 2;
+
+ d += (e << 5 | e >>> 27) + ffunc(a, b, c) + x[idx++] + y1;
+ a = a << 30 | a >>> 2;
+
+ c += (d << 5 | d >>> 27) + ffunc(e, a, b) + x[idx++] + y1;
+ e = e << 30 | e >>> 2;
+
+ b += (c << 5 | c >>> 27) + ffunc(d, e, a) + x[idx++] + y1;
+ d = d << 30 | d >>> 2;
+
+ a += (b << 5 | b >>> 27) + ffunc(c, d, e) + x[idx++] + y1;
+ c = c << 30 | c >>> 2;
+ }
+
+ //
+ // round 2
+ //
+ for (int j = 0; j < 4; j++) {
+ // E = rotateLeft(a, 5) + hfunc(b, c, d) + E + x[idx++] + y2
+ // B = rotateLeft(b, 30)
+ e += (a << 5 | a >>> 27) + hfunc(b, c, d) + x[idx++] + y2;
+ b = b << 30 | b >>> 2;
+
+ d += (e << 5 | e >>> 27) + hfunc(a, b, c) + x[idx++] + y2;
+ a = a << 30 | a >>> 2;
+
+ c += (d << 5 | d >>> 27) + hfunc(e, a, b) + x[idx++] + y2;
+ e = e << 30 | e >>> 2;
+
+ b += (c << 5 | c >>> 27) + hfunc(d, e, a) + x[idx++] + y2;
+ d = d << 30 | d >>> 2;
+
+ a += (b << 5 | b >>> 27) + hfunc(c, d, e) + x[idx++] + y2;
+ c = c << 30 | c >>> 2;
+ }
+
+ //
+ // round 3
+ //
+ for (int j = 0; j < 4; j++) {
+ // E = rotateLeft(a, 5) + gfunc(b, c, d) + E + x[idx++] + y3
+ // B = rotateLeft(b, 30)
+ e += (a << 5 | a >>> 27) + gfunc(b, c, d) + x[idx++] + y3;
+ b = b << 30 | b >>> 2;
+
+ d += (e << 5 | e >>> 27) + gfunc(a, b, c) + x[idx++] + y3;
+ a = a << 30 | a >>> 2;
+
+ c += (d << 5 | d >>> 27) + gfunc(e, a, b) + x[idx++] + y3;
+ e = e << 30 | e >>> 2;
+
+ b += (c << 5 | c >>> 27) + gfunc(d, e, a) + x[idx++] + y3;
+ d = d << 30 | d >>> 2;
+
+ a += (b << 5 | b >>> 27) + gfunc(c, d, e) + x[idx++] + y3;
+ c = c << 30 | c >>> 2;
+ }
+
+ //
+ // round 4
+ //
+ for (int j = 0; j <= 3; j++) {
+ // E = rotateLeft(a, 5) + hfunc(b, c, d) + E + x[idx++] + y4
+ // B = rotateLeft(b, 30)
+ e += (a << 5 | a >>> 27) + hfunc(b, c, d) + x[idx++] + y4;
+ b = b << 30 | b >>> 2;
+
+ d += (e << 5 | e >>> 27) + hfunc(a, b, c) + x[idx++] + y4;
+ a = a << 30 | a >>> 2;
+
+ c += (d << 5 | d >>> 27) + hfunc(e, a, b) + x[idx++] + y4;
+ e = e << 30 | e >>> 2;
+
+ b += (c << 5 | c >>> 27) + hfunc(d, e, a) + x[idx++] + y4;
+ d = d << 30 | d >>> 2;
+
+ a += (b << 5 | b >>> 27) + hfunc(c, d, e) + x[idx++] + y4;
+ c = c << 30 | c >>> 2;
+ }
+
+ h1 += a;
+ h2 += b;
+ h3 += c;
+ h4 += d;
+ h5 += e;
+
+ //
+ // reset start of the buffer.
+ //
+ xOff = 0;
+ for (int i = 0; i < 16; i++) {
+ x[i] = 0;
+ }
+ }
+
+ public void timeSHA1DigestProcessBlock(int iterations) {
+ for (int i = 0; i < iterations; i++) {
+ h1 = h2 = h3 = h4 = h5 = 0;
+ processBlock();
+ }
+ }
+
+ public boolean verifySHa1DigestProcessBlock() {
+ byte buf[] = SOURCE_Text.getBytes();
+ for (int i = 0; i < 80; i++) {
+ x[i] = buf[i];
+ }
+ processBlock();
+ return h1 == 1347341312 &&
+ h2 == -1669350125 &&
+ h3 == -362661148 &&
+ h4 == 1604346378 &&
+ h5 == -833338986;
+ }
+
+ /**
+ * Integer rotate right patterns.
+ */
+
+ int resultIntegerRightRegVCSubV;
+ int resultIntegerRightRegVNegV;
+
+ public static int rotateIntegerRightRegVCSubV(int value, int distance) {
+ return (value >>> distance) | (value << (32 - distance));
+ }
+
+ public static int rotateIntegerRightRegVNegV(int value, int distance) {
+ return (value >>> distance) | (value << -distance);
+ }
+
+ public void timeIntegerRotateRight(int iterations) {
+ for (int i = 0; i < iterations; i++) {
+ for (int distance = 0; distance < Integer.SIZE; distance++) {
+ resultIntegerRightRegVCSubV += rotateIntegerRightRegVCSubV(0xCAFEBABE, distance);
+ resultIntegerRightRegVNegV += rotateIntegerRightRegVNegV(0xCAFEBABE, distance);
+ }
+ }
+ }
+
+ public boolean verifyIntegerRotateRight() {
+ return (rotateIntegerRightRegVCSubV(0xCAFEBABE, 16) == 0xBABECAFE) &&
+ (rotateIntegerRightRegVNegV(0xCAFEBABE, -4) == 0xAFEBABEC);
+ }
+
+ /**
+ * Integer rotate left patterns.
+ */
+
+ int resultIntegerLeftRegCSubVV;
+ int resultIntegerLeftRegNegVV;
+
+ public static int rotateIntegerLeftRegCSubVV(int value, int distance) {
+ return (value >>> (32 - distance)) | (value << distance);
+ }
+
+ public static int rotateIntegerLeftRegNegVV(int value, int distance) {
+ return (value >>> -distance) | (value << distance);
+ }
+
+ public void timeIntegerRotateLeft(int iterations) {
+ for (int i = 0; i < iterations; i++) {
+ for (int distance = 0; distance < Integer.SIZE; distance++) {
+ resultIntegerLeftRegCSubVV += rotateIntegerLeftRegCSubVV(0xCAFEBABE, distance);
+ resultIntegerLeftRegNegVV += rotateIntegerLeftRegNegVV(0xCAFEBABE, distance);
+ }
+ }
+ }
+
+ public boolean verifyIntegerRotateLeft() {
+ return (rotateIntegerLeftRegCSubVV(0xCAFEBABE, 4) == 0xAFEBABEC) &&
+ (rotateIntegerLeftRegNegVV(0xCAFEBABE, -4) == 0xECAFEBAB);
+ }
+
+ /**
+ * Long rotate right patterns.
+ */
+
+ int resultLongRightRegVCSubV;
+ int resultLongRightRegVNegV;
+
+ public static long rotateLongRightRegVCSubV(long value, int distance) {
+ return (value >>> distance) | (value << (64 - distance));
+ }
+
+ public static long rotateLongRightRegVNegV(long value, int distance) {
+ return (value >>> distance) | (value << -distance);
+ }
+
+ public void timeLongRotateRight(int iterations) {
+ for (int i = 0; i < iterations; i++) {
+ for (int distance = 0; distance < Long.SIZE; distance++) {
+ resultLongRightRegVCSubV += rotateLongRightRegVCSubV(0xCAFEBABEBAADF00DL, distance);
+ resultLongRightRegVNegV += rotateLongRightRegVNegV(0xCAFEBABEBAADF00DL, distance);
+ }
+ }
+ }
+
+ public boolean verifyLongRotateRight() {
+ return (rotateLongRightRegVCSubV(0xCAFEBABEBAADF00DL, 32) == 0xBAADF00DCAFEBABEL) &&
+ (rotateLongRightRegVNegV(0xCAFEBABEBAADF00DL, -16) == 0xBABEBAADF00DCAFEL);
+ }
+
+ /**
+ * Long rotate left patterns.
+ */
+
+ int resultLongLeftRegCSubVV;
+ int resultLongLeftRegNegVV;
+
+ public static long rotateLongLeftRegCSubVV(long value, int distance) {
+ return (value >>> (64 - distance)) | (value << distance);
+ }
+
+ public static long rotateLongLeftRegNegVV(long value, int distance) {
+ return (value >>> -distance) | (value << distance);
+ }
+
+ public void timeLongRotateLeft(int iterations) {
+ for (int i = 0; i < iterations; i++) {
+ for (int distance = 0; distance < Long.SIZE; distance++) {
+ resultLongLeftRegCSubVV += rotateLongLeftRegCSubVV(0xCAFEBABEBAADF00DL, distance);
+ resultLongLeftRegNegVV += rotateLongLeftRegNegVV(0xCAFEBABEBAADF00DL, distance);
+ }
+ }
+ }
+
+ public boolean verifyLongRotateLeft() {
+ return (rotateLongLeftRegCSubVV(0xCAFEBABEBAADF00DL, 4) == 0xAFEBABEBAADF00DCL) &&
+ (rotateLongLeftRegNegVV(0xCAFEBABEBAADF00DL, -16) == 0xF00DCAFEBABEBAADL);
+ }
+
+ public static void main(String args[]) {
+ BitfieldRotate br = new BitfieldRotate();
+ long before = System.currentTimeMillis();
+ br.timeSHA1DigestProcessBlock(1000);
+ br.timeIntegerRotateRight(1000);
+ br.timeIntegerRotateLeft(1000);
+ br.timeLongRotateRight(1000);
+ br.timeLongRotateLeft(1000);
+ long after = System.currentTimeMillis();
+ System.out.println("BitfieldRotate: " + (after - before));
+ }
+}
+