1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 /**
  26  * @test
  27  * @bug 8074981
  28  * @summary Add C2 x86 Superword support for scalar product reduction optimizations : int test
  29  * @requires os.arch=="x86" | os.arch=="i386" | os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64"
  30  *
  31  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions
  32  *      -XX:LoopUnrollLimit=250 -XX:CompileThresholdScaling=0.1
  33  *      -XX:CompileCommand=exclude,compiler.loopopts.superword.ReductionPerf::main
  34  *      -XX:+SuperWordReductions
  35  *      compiler.loopopts.superword.ReductionPerf
  36  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions
  37  *      -XX:LoopUnrollLimit=250 -XX:CompileThresholdScaling=0.1
  38  *      -XX:CompileCommand=exclude,compiler.loopopts.superword.ReductionPerf::main
  39  *      -XX:-SuperWordReductions
  40  *      compiler.loopopts.superword.ReductionPerf
  41  */
  42 
  43 package compiler.loopopts.superword;
  44 
  45 public class ReductionPerf {
  46     public static void main(String[] args) throws Exception {
  47         int[] a1 = new int[8 * 1024];
  48         int[] a2 = new int[8 * 1024];
  49         int[] a3 = new int[8 * 1024];
  50         long[] b1 = new long[8 * 1024];
  51         long[] b2 = new long[8 * 1024];
  52         long[] b3 = new long[8 * 1024];
  53         float[] c1 = new float[8 * 1024];
  54         float[] c2 = new float[8 * 1024];
  55         float[] c3 = new float[8 * 1024];
  56         double[] d1 = new double[8 * 1024];
  57         double[] d2 = new double[8 * 1024];
  58         double[] d3 = new double[8 * 1024];
  59 
  60         ReductionInit(a1, a2, a3, b1, b2, b3, c1, c2, c3, d1, d2, d3);
  61 
  62         int sumIv = sumInt(a1, a2, a3);
  63         long sumLv = sumLong(b1, b2, b3);
  64         float sumFv = sumFloat(c1, c2, c3);
  65         double sumDv = sumDouble(d1, d2, d3);
  66         int mulIv = prodInt(a1, a2, a3);
  67         long mulLv = prodLong(b1, b2, b3);
  68         float mulFv = prodFloat(c1, c2, c3);
  69         double mulDv = prodDouble(d1, d2, d3);
  70 
  71         int sumI = 0;
  72         long sumL = 0;
  73         float sumF = 0.f;
  74         double sumD = 0.;
  75         int mulI = 0;
  76         long mulL = 0;
  77         float mulF = 0.f;
  78         double mulD = 0.;
  79 
  80         System.out.println("Warmup ...");
  81         long start = System.currentTimeMillis();
  82 
  83         for (int j = 0; j < 2000; j++) {
  84             sumI = sumInt(a1, a2, a3);
  85             sumL = sumLong(b1, b2, b3);
  86             sumF = sumFloat(c1, c2, c3);
  87             sumD = sumDouble(d1, d2, d3);
  88             mulI = prodInt(a1, a2, a3);
  89             mulL = prodLong(b1, b2, b3);
  90             mulF = prodFloat(c1, c2, c3);
  91             mulD = prodDouble(d1, d2, d3);
  92         }
  93 
  94         long stop = System.currentTimeMillis();
  95         System.out.println(" Warmup is done in " + (stop - start) + " msec");
  96 
  97         if (sumIv != sumI) {
  98             System.out.println("sum int:    " + sumIv + " != " + sumI);
  99         }
 100         if (sumLv != sumL) {
 101             System.out.println("sum long:   " + sumLv + " != " + sumL);
 102         }
 103         if (sumFv != sumF) {
 104             System.out.println("sum float:  " + sumFv + " != " + sumF);
 105         }
 106         if (sumDv != sumD) {
 107             System.out.println("sum double: " + sumDv + " != " + sumD);
 108         }
 109         if (mulIv != mulI) {
 110             System.out.println("prod int:    " + mulIv + " != " + mulI);
 111         }
 112         if (mulLv != mulL) {
 113             System.out.println("prod long:   " + mulLv + " != " + mulL);
 114         }
 115         if (mulFv != mulF) {
 116             System.out.println("prod float:  " + mulFv + " != " + mulF);
 117         }
 118         if (mulDv != mulD) {
 119             System.out.println("prod double: " + mulDv + " != " + mulD);
 120         }
 121 
 122         start = System.currentTimeMillis();
 123         for (int j = 0; j < 5000; j++) {
 124             sumI = sumInt(a1, a2, a3);
 125         }
 126         stop = System.currentTimeMillis();
 127         System.out.println("sum int:    " + (stop - start));
 128 
 129         start = System.currentTimeMillis();
 130         for (int j = 0; j < 5000; j++) {
 131             sumL = sumLong(b1, b2, b3);
 132         }
 133         stop = System.currentTimeMillis();
 134         System.out.println("sum long:   " + (stop - start));
 135 
 136         start = System.currentTimeMillis();
 137         for (int j = 0; j < 5000; j++) {
 138             sumF = sumFloat(c1, c2, c3);
 139         }
 140         stop = System.currentTimeMillis();
 141         System.out.println("sum float:  " + (stop - start));
 142 
 143         start = System.currentTimeMillis();
 144         for (int j = 0; j < 5000; j++) {
 145             sumD = sumDouble(d1, d2, d3);
 146         }
 147         stop = System.currentTimeMillis();
 148         System.out.println("sum double: " + (stop - start));
 149 
 150         start = System.currentTimeMillis();
 151         for (int j = 0; j < 5000; j++) {
 152             mulI = prodInt(a1, a2, a3);
 153         }
 154         stop = System.currentTimeMillis();
 155         System.out.println("prod int:    " + (stop - start));
 156 
 157         start = System.currentTimeMillis();
 158         for (int j = 0; j < 5000; j++) {
 159             mulL = prodLong(b1, b2, b3);
 160         }
 161         stop = System.currentTimeMillis();
 162         System.out.println("prod long:   " + (stop - start));
 163 
 164         start = System.currentTimeMillis();
 165         for (int j = 0; j < 5000; j++) {
 166             mulF = prodFloat(c1, c2, c3);
 167         }
 168         stop = System.currentTimeMillis();
 169         System.out.println("prod float:  " + (stop - start));
 170 
 171         start = System.currentTimeMillis();
 172         for (int j = 0; j < 5000; j++) {
 173             mulD = prodDouble(d1, d2, d3);
 174         }
 175         stop = System.currentTimeMillis();
 176         System.out.println("prod double: " + (stop - start));
 177 
 178     }
 179 
 180     public static void ReductionInit(int[] a1, int[] a2, int[] a3,
 181                                      long[] b1, long[] b2, long[] b3,
 182                                      float[] c1, float[] c2, float[] c3,
 183                                      double[] d1, double[] d2, double[] d3) {
 184         for(int i = 0; i < a1.length; i++) {
 185             a1[i] =          (i + 0);
 186             a2[i] =          (i + 1);
 187             a3[i] =          (i + 2);
 188             b1[i] =   (long) (i + 0);
 189             b2[i] =   (long) (i + 1);
 190             b3[i] =   (long) (i + 2);
 191             c1[i] =  (float) (i + 0);
 192             c2[i] =  (float) (i + 1);
 193             c3[i] =  (float) (i + 2);
 194             d1[i] = (double) (i + 0);
 195             d2[i] = (double) (i + 1);
 196             d3[i] = (double) (i + 2);
 197         }
 198     }
 199 
 200     public static int sumInt(int[] a1, int[] a2, int[] a3) {
 201         int total = 0;
 202         for (int i = 0; i < a1.length; i++) {
 203             total += (a1[i] * a2[i]) + (a1[i] * a3[i]) + (a2[i] * a3[i]);
 204         }
 205         return total;
 206     }
 207 
 208     public static long sumLong(long[] b1, long[] b2, long[] b3) {
 209         long total = 0;
 210         for (int i = 0; i < b1.length; i++) {
 211             total += (b1[i] * b2[i]) + (b1[i] * b3[i]) + (b2[i] * b3[i]);
 212         }
 213         return total;
 214     }
 215 
 216     public static float sumFloat(float[] c1, float[] c2, float[] c3) {
 217         float total = 0;
 218         for (int i = 0; i < c1.length; i++) {
 219             total += (c1[i] * c2[i]) + (c1[i] * c3[i]) + (c2[i] * c3[i]);
 220         }
 221         return total;
 222     }
 223 
 224     public static double sumDouble(double[] d1, double[] d2, double[] d3) {
 225         double total = 0;
 226         for (int i = 0; i < d1.length; i++) {
 227             total += (d1[i] * d2[i]) + (d1[i] * d3[i]) + (d2[i] * d3[i]);
 228         }
 229         return total;
 230     }
 231 
 232     public static int prodInt(int[] a1, int[] a2, int[] a3) {
 233         int total = 1;
 234         for (int i = 0; i < a1.length; i++) {
 235             total *= (a1[i] * a2[i]) + (a1[i] * a3[i]) + (a2[i] * a3[i]);
 236         }
 237         return total;
 238     }
 239 
 240     public static long prodLong(long[] b1, long[] b2, long[] b3) {
 241         long total = 1;
 242         for (int i = 0; i < b1.length; i++) {
 243             total *= (b1[i] * b2[i]) + (b1[i] * b3[i]) + (b2[i] * b3[i]);
 244         }
 245         return total;
 246     }
 247 
 248     public static float prodFloat(float[] c1, float[] c2, float[] c3) {
 249         float total = 1;
 250         for (int i = 0; i < c1.length; i++) {
 251             total *= (c1[i] * c2[i]) + (c1[i] * c3[i]) + (c2[i] * c3[i]);
 252         }
 253         return total;
 254     }
 255 
 256     public static double prodDouble(double[] d1, double[] d2, double[] d3) {
 257         double total = 1;
 258         for (int i = 0; i < d1.length; i++) {
 259             total *= (d1[i] * d2[i]) + (d1[i] * d3[i]) + (d2[i] * d3[i]);
 260         }
 261         return total;
 262     }
 263 }