Skip to content
Permalink
Browse files

Add benchmark to measure performance of VH adapters

Reviewed-by: jvernee, psandoz
  • Loading branch information
mcimadamore committed May 18, 2020
1 parent 0bc9c6b commit e2d2dba6f2c7c5ad1247be3cffc098b830242919
Showing with 161 additions and 0 deletions.
  1. +161 −0 test/micro/org/openjdk/bench/jdk/incubator/foreign/TestAdaptVarHandles.java
@@ -0,0 +1,161 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.openjdk.bench.jdk.incubator.foreign;

import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.MemoryHandles;
import jdk.incubator.foreign.MemoryLayout;
import jdk.incubator.foreign.MemoryLayouts;
import jdk.incubator.foreign.MemorySegment;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.VarHandle;
import java.util.concurrent.TimeUnit;

@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@State(org.openjdk.jmh.annotations.Scope.Thread)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(3)
public class TestAdaptVarHandles {

static class IntBox {

private final int value;

IntBox(int value) {
this.value = value;
}

int intValue() {
return value;
}
}

static final int ELEM_SIZE = 1_000_000;

static final MethodHandle INT_TO_INTBOX;
static final MethodHandle INTBOX_TO_INT;

static {
try {
INT_TO_INTBOX = MethodHandles.lookup()
.findConstructor(IntBox.class, MethodType.methodType(void.class, int.class));
INTBOX_TO_INT = MethodHandles.lookup()
.findVirtual(IntBox.class, "intValue", MethodType.methodType(int.class));
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}

static final VarHandle VH_int = MethodHandles.arrayElementVarHandle(int[].class);

static final VarHandle VH_box_int = MemoryHandles.filterValue(VH_int, INTBOX_TO_INT, INT_TO_INTBOX);

static final VarHandle VH_addr_int = MemoryLayout.ofSequence(MemoryLayouts.JAVA_INT)
.varHandle(int.class, MemoryLayout.PathElement.sequenceElement());

static final VarHandle VH_addr_box_int = MemoryHandles.filterValue(VH_addr_int, INTBOX_TO_INT, INT_TO_INTBOX);

static final MethodHandle MH_int = VH_int.toMethodHandle(VarHandle.AccessMode.GET);

static final MethodHandle MH_box_int = MethodHandles.filterReturnValue(MH_int, INT_TO_INTBOX);

int[] base = new int[ELEM_SIZE];
MemorySegment segment = MemorySegment.ofArray(base);

@Setup
public void setup() {
for (int i = 0; i < ELEM_SIZE; i++) {
base[i] = i;
}
}

@Benchmark
public int vh_loop() throws Throwable {
int sum = 0;
for (int i = 0; i < ELEM_SIZE; i++) {
sum += (int)VH_int.get(base, i);
}
return sum;
}

@Benchmark
public int vh_box_loop() throws Throwable {
int sum = 0;
for (int i = 0; i < ELEM_SIZE; i++) {
sum += ((IntBox)VH_box_int.get(base, i)).intValue();
}
return sum;
}

@Benchmark
public int mh_loop() throws Throwable {
int sum = 0;
for (int i = 0; i < ELEM_SIZE; i++) {
sum += (int)MH_int.invokeExact(base, i);
}
return sum;
}

@Benchmark
public int mh_box_loop() throws Throwable {
int sum = 0;
for (int i = 0; i < ELEM_SIZE; i++) {
sum += ((IntBox)MH_box_int.invokeExact(base, i)).intValue();
}
return sum;
}

@Benchmark
public int segment_loop() throws Throwable {
int sum = 0;
MemoryAddress baseAddress = segment.baseAddress();
for (int i = 0; i < ELEM_SIZE; i++) {
sum += (int)VH_addr_int.get(baseAddress, (long)i);
}
return sum;
}

@Benchmark
public int segment_box_loop() throws Throwable {
int sum = 0;
MemoryAddress baseAddress = segment.baseAddress();
for (int i = 0; i < ELEM_SIZE; i++) {
sum += ((IntBox)VH_addr_box_int.get(baseAddress, (long)i)).intValue();
}
return sum;
}
}

0 comments on commit e2d2dba

Please sign in to comment.
You can’t perform that action at this time.