1 /*
  2  * Copyright (c) 2018, 2021, 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.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 package org.openjdk.bench.jdk.incubator.vector.operation;
 26 
 27 import jdk.incubator.vector.*;
 28 import jdk.incubator.vector.VectorSpecies;
 29 import org.openjdk.jmh.annotations.*;
 30 
 31 import java.util.Arrays;
 32 import java.util.concurrent.TimeUnit;
 33 
 34 @BenchmarkMode(Mode.Throughput)
 35 @Warmup(iterations = 3, time = 1)
 36 @Measurement(iterations = 5, time = 1)
 37 @OutputTimeUnit(TimeUnit.MILLISECONDS)
 38 @State(Scope.Benchmark)
 39 @Fork(value = 1, jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"})
 40 public class Merge extends AbstractVectorBenchmark {
 41 
 42     @Param({"64", "1024", "65536"})
 43     int size;
 44 
 45     int[] in, out;
 46 
 47     @Setup
 48     public void setup() {
 49         size = size + (size % 64); // FIXME: process tails
 50         in  = new int[size];
 51         out = new int[size];
 52         for (int i = 0; i < size; i++) {
 53             in[i] = i;
 54         }
 55     }
 56 
 57     @Benchmark
 58     public void merge64_128() {
 59         merge(I64, I128);
 60     }
 61 
 62     @Benchmark
 63     public void merge128_256() {
 64         merge(I128, I256);
 65     }
 66 
 67     @Benchmark
 68     public void merge256_512() {
 69         merge(I256, I512);
 70     }
 71 
 72     @Benchmark
 73     public void merge64_256() {
 74         merge(I64, I256);
 75     }
 76 
 77     @Benchmark
 78     public void merge128_512() {
 79         merge(I128, I512);
 80     }
 81 
 82     @Benchmark
 83     public void merge64_512() {
 84         merge(I64, I256);
 85     }
 86 
 87     IntVector merge(VectorSpecies<Integer> from, VectorSpecies<Integer> to, int idx) {
 88         assert from.length() <= to.length();
 89 
 90         int vlenFrom = from.length();
 91         int vlenTo   =   to.length();
 92 
 93         if (vlenFrom == vlenTo) {
 94             return IntVector.fromArray(from, in, idx);
 95         } else {
 96             var stepDown = narrow(to);
 97             int mid = stepDown.length();
 98             var lo = merge(from, stepDown, idx);
 99             var hi = merge(from, stepDown, idx + mid);
100             return join(stepDown, to, lo, hi);
101         }
102     }
103 
104 
105     void merge(VectorSpecies<Integer> from, VectorSpecies<Integer> to) {
106         int vlenTo = to.length();
107         for (int i = 0; i < in.length; i += vlenTo) {
108             var r = merge(from, to, i);
109             r.intoArray(out, i);
110         }
111     }
112 
113     @TearDown
114     public void tearDown() {
115         assert Arrays.deepEquals(new Object[] {in}, new Object[] {out});
116     }
117 }