1 /*
  2  * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
  3  * Copyright (c) 2021, Alibaba Group Holding Limited. All Rights Reserved.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.
  9  *
 10  * This code is distributed in the hope that it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  */
 24 
 25 package org.openjdk.bench.jdk.incubator.vector.bigdata;
 26 
 27 import java.util.concurrent.TimeUnit;
 28 import java.util.random.RandomGenerator;
 29 
 30 import jdk.incubator.vector.IntVector;
 31 import jdk.incubator.vector.VectorSpecies;
 32 import jdk.incubator.vector.VectorMask;
 33 import jdk.incubator.vector.VectorOperators;
 34 
 35 import org.openjdk.jmh.annotations.*;
 36 
 37 @BenchmarkMode(Mode.Throughput)
 38 @OutputTimeUnit(TimeUnit.MILLISECONDS)
 39 @State(Scope.Benchmark)
 40 @Warmup(iterations = 10, time = 1)
 41 @Measurement(iterations = 10, time = 1)
 42 @Fork(value = 1, jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"})
 43 public class SelectiveStore {
 44 
 45   @Param("1024")
 46   int ARRAY_LENGTH;
 47 
 48   private static final VectorSpecies<Integer> INT_64_SPECIES =
 49     IntVector.SPECIES_64;
 50   private static final VectorSpecies<Integer> INT_128_SPECIES =
 51     IntVector.SPECIES_128;
 52   private static final VectorSpecies<Integer> INT_256_SPECIES =
 53     IntVector.SPECIES_256;
 54   private static final VectorSpecies<Integer> INT_512_SPECIES =
 55     IntVector.SPECIES_512;
 56   private static final VectorSpecies<Integer> INT_PREFERRED_SPECIES =
 57     IntVector.SPECIES_PREFERRED;
 58 
 59   private int conflict_cnt;
 60   private int[] index;
 61   private int[] input1;
 62   private int[] input2;
 63   private int[] conflict_array;
 64 
 65   @Setup
 66   public void init() {
 67     index = new int[ARRAY_LENGTH];
 68     input1 = new int[ARRAY_LENGTH];
 69     input2 = new int[ARRAY_LENGTH];
 70     conflict_array = new int[ARRAY_LENGTH];
 71 
 72     RandomGenerator rng = RandomGenerator.getDefault();
 73     int conflict_id_each_5_elements = rng.nextInt(5);
 74 
 75     for (int i = 0; i < ARRAY_LENGTH; i++) {
 76       index[i] = rng.nextInt(ARRAY_LENGTH);
 77       input1[i] = rng.nextInt();
 78       // Generate 20% conflict data
 79       int remainder = i % 5;
 80       if (remainder == conflict_id_each_5_elements) {
 81         input2[i] = rng.nextInt();
 82       } else {
 83         input2[i] = input1[i];
 84       }
 85       conflict_array[i] = 0;
 86     }
 87   }
 88 
 89   private void selectiveStore(VectorSpecies<Integer> species) {
 90     conflict_cnt = 0;
 91     for (int i = 0; i < ARRAY_LENGTH; i += species.length()) {
 92       IntVector av = IntVector.fromArray(species, input1, i);
 93       IntVector bv = IntVector.fromArray(species, input2, i);
 94       IntVector cv = IntVector.fromArray(species, index, i);
 95       VectorMask<Integer> mask = av.compare(VectorOperators.NE, bv);
 96       IntVector dv = cv.compress(mask);
 97       dv.intoArray(conflict_array, conflict_cnt, mask.compress());
 98       conflict_cnt += mask.trueCount();
 99     }
100   }
101 
102   @Benchmark
103   public void selectiveStore_scalar() {
104     conflict_cnt = 0;
105     for (int i = 0; i < ARRAY_LENGTH; i++) {
106       if (input1[i] != input2[i]) {
107         conflict_array[conflict_cnt] = index[i];
108         conflict_cnt++;
109       }
110     }
111   }
112 
113   @Benchmark
114   public void selectiveStore_vector_64() {
115     selectiveStore(INT_64_SPECIES);
116   }
117 
118   @Benchmark
119   public void selectiveStore_vector_128() {
120     selectiveStore(INT_128_SPECIES);
121   }
122 
123   @Benchmark
124   public void selectiveStore_vector_256() {
125     selectiveStore(INT_256_SPECIES);
126   }
127 
128   @Benchmark
129   public void selectiveStore_vector_512() {
130     selectiveStore(INT_512_SPECIES);
131   }
132 
133   @Benchmark
134   public void selectiveStore_vector_preferred() {
135     selectiveStore(INT_PREFERRED_SPECIES);
136   }
137 }
138