1 /* 2 * Copyright (c) 2021, 2022, 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; 25 26 import java.lang.foreign.Arena; 27 import java.lang.foreign.MemorySegment; 28 import java.nio.ByteOrder; 29 import java.util.concurrent.TimeUnit; 30 import jdk.incubator.vector.ByteVector; 31 import jdk.incubator.vector.VectorOperators; 32 import jdk.incubator.vector.VectorSpecies; 33 import org.openjdk.jmh.annotations.Benchmark; 34 import org.openjdk.jmh.annotations.BenchmarkMode; 35 import org.openjdk.jmh.annotations.CompilerControl; 36 import org.openjdk.jmh.annotations.Fork; 37 import org.openjdk.jmh.annotations.Measurement; 38 import org.openjdk.jmh.annotations.Mode; 39 import org.openjdk.jmh.annotations.OutputTimeUnit; 40 import org.openjdk.jmh.annotations.Param; 41 import org.openjdk.jmh.annotations.Setup; 42 import org.openjdk.jmh.annotations.State; 43 import org.openjdk.jmh.annotations.Warmup; 44 45 @BenchmarkMode(Mode.AverageTime) 46 @Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS) 47 @Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) 48 @State(org.openjdk.jmh.annotations.Scope.Thread) 49 @OutputTimeUnit(TimeUnit.NANOSECONDS) 50 @Fork(value = 1, jvmArgsAppend = { 51 "--add-modules=jdk.incubator.vector", 52 "--enable-native-access", "ALL-UNNAMED", 53 "-Djdk.incubator.vector.VECTOR_ACCESS_OOB_CHECK=1"}) 54 public class TestLoadStoreBytes { 55 private static final VectorSpecies<Byte> SPECIES = VectorSpecies.ofLargestShape(byte.class); 56 57 @Param("1024") 58 private int size; 59 60 private byte[] srcArray; 61 62 private byte[] dstArray; 63 64 65 private MemorySegment srcSegmentHeap; 66 67 private MemorySegment dstSegmentHeap; 68 69 private MemorySegment srcSegment; 70 71 private MemorySegment dstSegment; 72 73 private byte[] a, b, c; 74 75 @Setup 76 public void setup() { 77 srcArray = new byte[size]; 78 dstArray = srcArray.clone(); 79 for (int i = 0; i < srcArray.length; i++) { 80 srcArray[i] = (byte) i; 81 } 82 83 srcSegmentHeap = MemorySegment.ofArray(new byte[size]); 84 dstSegmentHeap = MemorySegment.ofArray(new byte[size]); 85 86 srcSegment = Arena.ofAuto().allocate(size, SPECIES.vectorByteSize()); 87 dstSegment = Arena.ofAuto().allocate(size, SPECIES.vectorByteSize()); 88 89 a = new byte[size]; 90 b = new byte[size]; 91 c = new byte[size]; 92 } 93 94 95 @Benchmark 96 public void array() { 97 for (int i = 0; i < SPECIES.loopBound(srcArray.length); i += SPECIES.length()) { 98 var v = ByteVector.fromArray(SPECIES, srcArray, i); 99 v.intoArray(dstArray, i); 100 } 101 } 102 103 @Benchmark 104 public void arrayScalar() { 105 for (int i = 0; i < SPECIES.loopBound(srcArray.length); i ++) { 106 var v = srcArray[i]; 107 dstArray[i] = v; 108 } 109 } 110 111 @Benchmark 112 public void vectAdd1() { 113 var a = this.a; 114 var b = this.b; 115 var c = this.c; 116 117 for (int i = 0; i < a.length; i += SPECIES.length()) { 118 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 119 ByteVector bv = ByteVector.fromArray(SPECIES, b, i); 120 av.lanewise(VectorOperators.ADD, bv).intoArray(c, i); 121 } 122 } 123 124 @Benchmark 125 public void vectAdd2() { 126 var a = this.a; 127 var b = this.b; 128 var c = this.c; 129 130 for (int i = 0; i < a.length/SPECIES.length(); i++) { 131 ByteVector av = ByteVector.fromArray(SPECIES, a, (i*SPECIES.length())); 132 ByteVector bv = ByteVector.fromArray(SPECIES, b, (i*SPECIES.length())); 133 av.lanewise(VectorOperators.ADD, bv).intoArray(c, (i*SPECIES.length())); 134 } 135 } 136 137 @Benchmark 138 public void arrayAdd() { 139 for (int i = 0; i < SPECIES.loopBound(srcArray.length); i += SPECIES.length()) { 140 var v = ByteVector.fromArray(SPECIES, srcArray, i); 141 v = v.add(v); 142 v.intoArray(dstArray, i); 143 } 144 } 145 146 @Benchmark 147 public void segmentHeap() { 148 for (long i = 0; i < SPECIES.loopBound(srcArray.length); i += SPECIES.length()) { 149 var v = ByteVector.fromMemorySegment(SPECIES, srcSegmentHeap, i, ByteOrder.nativeOrder()); 150 v.intoMemorySegment(dstSegmentHeap, i, ByteOrder.nativeOrder()); 151 } 152 } 153 154 @Benchmark 155 public void segmentNativeImplicit() { 156 for (long i = 0; i < SPECIES.loopBound(srcArray.length); i += SPECIES.length()) { 157 var v = ByteVector.fromMemorySegment(SPECIES, srcSegment, i, ByteOrder.nativeOrder()); 158 v.intoMemorySegment(dstSegment, i, ByteOrder.nativeOrder()); 159 } 160 } 161 162 @Benchmark 163 public void segmentNativeConfined() { 164 try (final var arena = Arena.ofConfined()) { 165 final var srcSegmentConfined = srcSegment.reinterpret(arena, null); 166 final var dstSegmentConfined = dstSegment.reinterpret(arena, null); 167 168 for (long i = 0; i < SPECIES.loopBound(srcArray.length); i += SPECIES.length()) { 169 var v = ByteVector.fromMemorySegment(SPECIES, srcSegmentConfined, i, ByteOrder.nativeOrder()); 170 v.intoMemorySegment(dstSegmentConfined, i, ByteOrder.nativeOrder()); 171 } 172 } 173 } 174 }