1 /*
2 * Copyright (c) 2018, 2024, 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 package org.openjdk.bench.jdk.incubator.vector.operation;
25
26 #warn This file is preprocessed before being compiled
27
28 import java.util.concurrent.TimeUnit;
29 import java.util.function.IntFunction;
30 import jdk.incubator.vector.VectorMath;
31
32 import org.openjdk.jmh.annotations.*;
33 import org.openjdk.jmh.infra.Blackhole;
34
35 @BenchmarkMode(Mode.Throughput)
36 @OutputTimeUnit(TimeUnit.MILLISECONDS)
37 @State(Scope.Benchmark)
38 @Warmup(iterations = 3, time = 1)
39 @Measurement(iterations = 5, time = 1)
40 @Fork(value = 1, jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"})
41 public class $Type$Scalar extends AbstractVectorBenchmark {
42 static final int INVOC_COUNT = 1; // To align with vector benchmarks.
43
44 #if[BITWISE]
45 private static final $type$ CONST_SHIFT = $Boxtype$.SIZE / 2;
46 #end[BITWISE]
47
48 @Param("1024")
49 int size;
50
51 $type$[] fill(IntFunction<$Wideboxtype$> f) {
52 $type$[] array = new $type$[size];
53 for (int i = 0; i < array.length; i++) {
54 array[i] = f.apply(i);
55 }
56 return array;
57 }
58
59 static $bitstype$ bits($type$ e) {
60 return {#if[FP]?$Type$.$type$To$Bitstype$Bits(e):e};
61 }
62
63 $type$[] as, bs, cs, rs;
64 boolean[] ms, mt, rms;
65 int[] ss;
66
67 @Setup
68 public void init() {
69 as = fill(i -> ($type$)(2*i));
70 bs = fill(i -> ($type$)(i+1));
71 cs = fill(i -> ($type$)(i+5));
72 rs = fill(i -> ($type$)0);
73 ms = fillMask(size, i -> (i % 2) == 0);
74 mt = fillMask(size, i -> true);
75 rms = fillMask(size, i -> false);
76
77 ss = fillInt(size, i -> RAND.nextInt(Math.max(i,1)));
78 }
79
80 final IntFunction<$type$[]> fa = vl -> as;
81 final IntFunction<$type$[]> fb = vl -> bs;
82 final IntFunction<$type$[]> fc = vl -> cs;
83 final IntFunction<$type$[]> fr = vl -> rs;
84 final IntFunction<boolean[]> fm = vl -> ms;
85 final IntFunction<boolean[]> fmt = vl -> mt;
86 final IntFunction<boolean[]> fmr = vl -> rms;
87 final IntFunction<int[]> fs = vl -> ss;
88
89 static boolean eq($type$ a, $type$ b) {
90 return a == b;
91 }
92
93 static boolean neq($type$ a, $type$ b) {
94 return a != b;
95 }
96
97 static boolean lt($type$ a, $type$ b) {
98 return a < b;
99 }
100
101 static boolean le($type$ a, $type$ b) {
102 return a <= b;
103 }
104
105 static boolean gt($type$ a, $type$ b) {
106 return a > b;
107 }
108
109 static boolean ge($type$ a, $type$ b) {
110 return a >= b;
111 }
112
113 #if[!FP]
114 static boolean ult($type$ a, $type$ b) {
115 return $Boxtype$.compareUnsigned(a, b) < 0;
116 }
117
118 static boolean ule($type$ a, $type$ b) {
119 return $Boxtype$.compareUnsigned(a, b) <= 0;
120 }
121
122 static boolean ugt($type$ a, $type$ b) {
123 return $Boxtype$.compareUnsigned(a, b) > 0;
124 }
125
126 static boolean uge($type$ a, $type$ b) {
127 return $Boxtype$.compareUnsigned(a, b) >= 0;
128 }
129 #end[!FP]
130
131 #if[BITWISE]
132 static $type$ ROL_scalar($type$ a, $type$ b) {
133 #if[intOrLong]
134 return $Wideboxtype$.rotateLeft(a, ((int)b));
135 #else[intOrLong]
136 #if[short]
137 return (short)(((((short)a) & 0xFFFF) << (b & 15)) | ((((short)a) & 0xFFFF) >>> (16 - (b & 15))));
138 #else[short]
139 return (byte)(((((byte)a) & 0xFF) << (b & 7)) | ((((byte)a) & 0xFF) >>> (8 - (b & 7))));
140 #end[short]
141 #end[intOrLong]
142 }
143
144 static $type$ ROR_scalar($type$ a, $type$ b) {
145 #if[intOrLong]
146 return $Wideboxtype$.rotateRight(a, ((int)b));
147 #else[intOrLong]
148 #if[short]
149 return (short)(((((short)a) & 0xFFFF) >>> (b & 15)) | ((((short)a) & 0xFFFF) << (16 - (b & 15))));
150 #else[short]
151 return (byte)(((((byte)a) & 0xFF) >>> (b & 7)) | ((((byte)a) & 0xFF) << (8 - (b & 7))));
152 #end[short]
153 #end[intOrLong]
154 }
155
156 static $type$ TRAILING_ZEROS_COUNT_scalar($type$ a) {
157 #if[intOrLong]
158 return $Wideboxtype$.numberOfTrailingZeros(a);
159 #else[intOrLong]
160 #if[short]
161 return (short) (a != 0 ? Integer.numberOfTrailingZeros(a) : 16);
162 #else[short]
163 return (byte) (a != 0 ? Integer.numberOfTrailingZeros(a) : 8);
164 #end[short]
165 #end[intOrLong]
166 }
167
168 static $type$ LEADING_ZEROS_COUNT_scalar($type$ a) {
169 #if[intOrLong]
170 return $Wideboxtype$.numberOfLeadingZeros(a);
171 #else[intOrLong]
172 #if[short]
173 return (short) (a >= 0 ? Integer.numberOfLeadingZeros(a) - 16 : 0);
174 #else[short]
175 return (byte) (a >= 0 ? Integer.numberOfLeadingZeros(a) - 24 : 0);
176 #end[short]
177 #end[intOrLong]
178 }
179
180 static $type$ REVERSE_scalar($type$ a) {
181 #if[intOrLong]
182 return $Wideboxtype$.reverse(a);
183 #else[intOrLong]
184 #if[short]
185 $type$ b = ROL_scalar(a, ($type$) 8);
186 b = (short)(((b & 0x5555) << 1) | ((b & 0xAAAA) >>> 1));
187 b = (short)(((b & 0x3333) << 2) | ((b & 0xCCCC) >>> 2));
188 b = (short)(((b & 0x0F0F) << 4) | ((b & 0xF0F0) >>> 4));
189 return b;
190 #else[short]
191 $type$ b = ROL_scalar(a, ($type$) 4);
192 b = (byte)(((b & 0x55) << 1) | ((b & 0xAA) >>> 1));
193 b = (byte)(((b & 0x33) << 2) | ((b & 0xCC) >>> 2));
194 return b;
195 #end[short]
196 #end[intOrLong]
197 }
198 #end[BITWISE]