mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8257074: Update the ByteBuffers micro benchmark
Reviewed-by: redestad, dfuchs, jvernee, bpb
This commit is contained in:
parent
7ed591cc9a
commit
ac276bb394
11 changed files with 2858 additions and 255 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,12 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
* published by the Free Software Foundation.
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
*
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
@ -24,43 +22,268 @@
|
||||||
*/
|
*/
|
||||||
package org.openjdk.bench.java.nio;
|
package org.openjdk.bench.java.nio;
|
||||||
|
|
||||||
import java.nio.CharBuffer;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.openjdk.jmh.annotations.Benchmark;
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
import org.openjdk.jmh.annotations.Level;
|
import org.openjdk.jmh.annotations.Fork;
|
||||||
|
import org.openjdk.jmh.annotations.Measurement;
|
||||||
import org.openjdk.jmh.annotations.Mode;
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
import org.openjdk.jmh.annotations.Param;
|
import org.openjdk.jmh.annotations.Param;
|
||||||
import org.openjdk.jmh.annotations.Scope;
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
import org.openjdk.jmh.annotations.Setup;
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
import org.openjdk.jmh.annotations.State;
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
import java.nio.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import static java.nio.ByteOrder.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark for memory access operations on java.nio.Buffer ( and its views )
|
||||||
|
*
|
||||||
|
* A large number of variants are covered. The individual benchmarks conform to
|
||||||
|
* the following convention:
|
||||||
|
* test(Direct|Heap)(Bulk|Loop)(Get|Put)Char(View)?(Swap)?(RO)?
|
||||||
|
*
|
||||||
|
* This allows to easily run a subset of particular interest. For example:
|
||||||
|
* Direct only :- "org.openjdk.bench.java.nio.CharBuffers.testDirect.*"
|
||||||
|
* Bulk only :- "org.openjdk.bench.java.nio.CharBuffers.test.*Bulk.*"
|
||||||
|
* Loop Put Swapped Views: -
|
||||||
|
* test(Direct|Heap)(Loop)(Put)Char(View)+(Swap)+"
|
||||||
|
*/
|
||||||
@BenchmarkMode(Mode.AverageTime)
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
@State(Scope.Thread)
|
@State(Scope.Thread)
|
||||||
|
@Fork(3)
|
||||||
public class CharBuffers {
|
public class CharBuffers {
|
||||||
|
|
||||||
@Param({"2", "256", "16384"})
|
static final int CARRIER_BYTE_WIDTH = 2;
|
||||||
public int numChars;
|
|
||||||
|
|
||||||
public String str;
|
@Param({"16", "1024", "131072"})
|
||||||
public CharBuffer buf;
|
private int size;
|
||||||
|
|
||||||
@Setup(Level.Iteration)
|
public char charValue;
|
||||||
public void createString() {
|
public char[] charArray;
|
||||||
char[] c = new char[numChars];
|
|
||||||
Arrays.fill(c, 'X');
|
public CharBuffer heapCharBuffer;
|
||||||
str = String.valueOf(c);
|
public CharBuffer heapCharBufferRO;
|
||||||
buf = CharBuffer.allocate(numChars);
|
public CharBuffer heapByteBufferAsCharBufferView;
|
||||||
|
public CharBuffer heapByteBufferAsCharBufferViewRO;
|
||||||
|
public CharBuffer heapByteBufferAsCharBufferViewSwap;
|
||||||
|
public CharBuffer heapByteBufferAsCharBufferViewSwapRO;
|
||||||
|
public CharBuffer directByteBufferAsCharBufferView;
|
||||||
|
public CharBuffer directByteBufferAsCharBufferViewRO;
|
||||||
|
public CharBuffer directByteBufferAsCharBufferViewSwap;
|
||||||
|
public CharBuffer directByteBufferAsCharBufferViewSwapRO;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
charArray = new char[size / CARRIER_BYTE_WIDTH];
|
||||||
|
|
||||||
|
// explicitly allocated heap carrier buffer
|
||||||
|
heapCharBuffer = CharBuffer.allocate(size / CARRIER_BYTE_WIDTH);
|
||||||
|
heapCharBufferRO = CharBuffer.allocate(size / CARRIER_BYTE_WIDTH).asReadOnlyBuffer();
|
||||||
|
|
||||||
|
// ByteBuffer views
|
||||||
|
heapByteBufferAsCharBufferView = ByteBuffer.allocate(size).order(nativeOrder()).asCharBuffer();
|
||||||
|
heapByteBufferAsCharBufferViewRO = ByteBuffer.allocate(size).order(nativeOrder()).asCharBuffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAsCharBufferView = ByteBuffer.allocateDirect(size).order(nativeOrder()).asCharBuffer();
|
||||||
|
directByteBufferAsCharBufferViewRO = ByteBuffer.allocateDirect(size).order(nativeOrder()).asCharBuffer().asReadOnlyBuffer();
|
||||||
|
|
||||||
|
// endianness swapped
|
||||||
|
ByteOrder nonNativeOrder = nativeOrder() == BIG_ENDIAN ? LITTLE_ENDIAN : BIG_ENDIAN;
|
||||||
|
heapByteBufferAsCharBufferViewSwap = ByteBuffer.allocate(size).order(nonNativeOrder).asCharBuffer();
|
||||||
|
heapByteBufferAsCharBufferViewSwapRO = ByteBuffer.allocate(size).order(nonNativeOrder).asCharBuffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAsCharBufferViewSwap = ByteBuffer.allocateDirect(size).order(nonNativeOrder).asCharBuffer();
|
||||||
|
directByteBufferAsCharBufferViewSwapRO = ByteBuffer.allocateDirect(size).order(nonNativeOrder).asCharBuffer().asReadOnlyBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------- HELPER METHODS
|
||||||
|
|
||||||
|
private int innerLoopGetChar(CharBuffer buf) {
|
||||||
|
int r = 0;
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
r += buf.get(i);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void innerLoopPutChar(CharBuffer buf) {
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
buf.put(i, charValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap___
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public char[] testHeapBulkPutChar() {
|
||||||
|
heapCharBuffer.put(0, charArray);
|
||||||
|
return charArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
public CharBuffer putString() {
|
public char[] testHeapBulkGetChar() {
|
||||||
buf.clear();
|
heapCharBuffer.get(0, charArray);
|
||||||
return buf.put(str);
|
return charArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutChar() {
|
||||||
|
innerLoopPutChar(heapCharBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetChar() {
|
||||||
|
return innerLoopGetChar(heapCharBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View_Swap_RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public char[] testHeapBulkGetCharViewSwapRO() {
|
||||||
|
heapByteBufferAsCharBufferViewSwapRO.get(0, charArray);
|
||||||
|
return charArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetCharViewSwapRO() {
|
||||||
|
return innerLoopGetChar(heapByteBufferAsCharBufferViewSwapRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View_Swap_
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public char[] testHeapBulkPutCharViewSwap() {
|
||||||
|
heapByteBufferAsCharBufferViewSwap.put(0, charArray);
|
||||||
|
return charArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public char[] testHeapBulkGetCharViewSwap() {
|
||||||
|
heapByteBufferAsCharBufferViewSwap.get(0, charArray);
|
||||||
|
return charArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutCharViewSwap() {
|
||||||
|
innerLoopPutChar(heapByteBufferAsCharBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetCharViewSwap() {
|
||||||
|
return innerLoopGetChar(heapByteBufferAsCharBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View__RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public char[] testHeapBulkGetCharViewRO() {
|
||||||
|
heapByteBufferAsCharBufferViewRO.get(0, charArray);
|
||||||
|
return charArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetCharViewRO() {
|
||||||
|
return innerLoopGetChar(heapByteBufferAsCharBufferViewRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View__
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public char[] testHeapBulkPutCharView() {
|
||||||
|
heapByteBufferAsCharBufferView.put(0, charArray);
|
||||||
|
return charArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public char[] testHeapBulkGetCharView() {
|
||||||
|
heapByteBufferAsCharBufferView.get(0, charArray);
|
||||||
|
return charArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutCharView() {
|
||||||
|
innerLoopPutChar(heapByteBufferAsCharBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetCharView() {
|
||||||
|
return innerLoopGetChar(heapByteBufferAsCharBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View_Swap_RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public char[] testDirectBulkGetCharViewSwapRO() {
|
||||||
|
directByteBufferAsCharBufferViewSwapRO.get(0, charArray);
|
||||||
|
return charArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetCharViewSwapRO() {
|
||||||
|
return innerLoopGetChar(directByteBufferAsCharBufferViewSwapRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View_Swap_
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public char[] testDirectBulkPutCharViewSwap() {
|
||||||
|
directByteBufferAsCharBufferViewSwap.put(0, charArray);
|
||||||
|
return charArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public char[] testDirectBulkGetCharViewSwap() {
|
||||||
|
directByteBufferAsCharBufferViewSwap.get(0, charArray);
|
||||||
|
return charArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testDirectLoopPutCharViewSwap() {
|
||||||
|
innerLoopPutChar(directByteBufferAsCharBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetCharViewSwap() {
|
||||||
|
return innerLoopGetChar(directByteBufferAsCharBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View__RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public char[] testDirectBulkGetCharViewRO() {
|
||||||
|
directByteBufferAsCharBufferViewRO.get(0, charArray);
|
||||||
|
return charArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetCharViewRO() {
|
||||||
|
return innerLoopGetChar(directByteBufferAsCharBufferViewRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View__
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public char[] testDirectBulkPutCharView() {
|
||||||
|
directByteBufferAsCharBufferView.put(0, charArray);
|
||||||
|
return charArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public char[] testDirectBulkGetCharView() {
|
||||||
|
directByteBufferAsCharBufferView.get(0, charArray);
|
||||||
|
return charArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testDirectLoopPutCharView() {
|
||||||
|
innerLoopPutChar(directByteBufferAsCharBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetCharView() {
|
||||||
|
return innerLoopGetChar(directByteBufferAsCharBufferView);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
289
test/micro/org/openjdk/bench/java/nio/DoubleBuffers.java
Normal file
289
test/micro/org/openjdk/bench/java/nio/DoubleBuffers.java
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 2021, 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.java.nio;
|
||||||
|
|
||||||
|
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.Param;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
import java.nio.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import static java.nio.ByteOrder.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark for memory access operations on java.nio.Buffer ( and its views )
|
||||||
|
*
|
||||||
|
* A large number of variants are covered. The individual benchmarks conform to
|
||||||
|
* the following convention:
|
||||||
|
* test(Direct|Heap)(Bulk|Loop)(Get|Put)Double(View)?(Swap)?(RO)?
|
||||||
|
*
|
||||||
|
* This allows to easily run a subset of particular interest. For example:
|
||||||
|
* Direct only :- "org.openjdk.bench.java.nio.DoubleBuffers.testDirect.*"
|
||||||
|
* Bulk only :- "org.openjdk.bench.java.nio.DoubleBuffers.test.*Bulk.*"
|
||||||
|
* Loop Put Swapped Views: -
|
||||||
|
* test(Direct|Heap)(Loop)(Put)Double(View)+(Swap)+"
|
||||||
|
*/
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@State(Scope.Thread)
|
||||||
|
@Fork(3)
|
||||||
|
public class DoubleBuffers {
|
||||||
|
|
||||||
|
static final int CARRIER_BYTE_WIDTH = 8;
|
||||||
|
|
||||||
|
@Param({"16", "1024", "131072"})
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
public double doubleValue;
|
||||||
|
public double[] doubleArray;
|
||||||
|
|
||||||
|
public DoubleBuffer heapDoubleBuffer;
|
||||||
|
public DoubleBuffer heapDoubleBufferRO;
|
||||||
|
public DoubleBuffer heapByteBufferAsDoubleBufferView;
|
||||||
|
public DoubleBuffer heapByteBufferAsDoubleBufferViewRO;
|
||||||
|
public DoubleBuffer heapByteBufferAsDoubleBufferViewSwap;
|
||||||
|
public DoubleBuffer heapByteBufferAsDoubleBufferViewSwapRO;
|
||||||
|
public DoubleBuffer directByteBufferAsDoubleBufferView;
|
||||||
|
public DoubleBuffer directByteBufferAsDoubleBufferViewRO;
|
||||||
|
public DoubleBuffer directByteBufferAsDoubleBufferViewSwap;
|
||||||
|
public DoubleBuffer directByteBufferAsDoubleBufferViewSwapRO;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
doubleArray = new double[size / CARRIER_BYTE_WIDTH];
|
||||||
|
|
||||||
|
// explicitly allocated heap carrier buffer
|
||||||
|
heapDoubleBuffer = DoubleBuffer.allocate(size / CARRIER_BYTE_WIDTH);
|
||||||
|
heapDoubleBufferRO = DoubleBuffer.allocate(size / CARRIER_BYTE_WIDTH).asReadOnlyBuffer();
|
||||||
|
|
||||||
|
// ByteBuffer views
|
||||||
|
heapByteBufferAsDoubleBufferView = ByteBuffer.allocate(size).order(nativeOrder()).asDoubleBuffer();
|
||||||
|
heapByteBufferAsDoubleBufferViewRO = ByteBuffer.allocate(size).order(nativeOrder()).asDoubleBuffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAsDoubleBufferView = ByteBuffer.allocateDirect(size).order(nativeOrder()).asDoubleBuffer();
|
||||||
|
directByteBufferAsDoubleBufferViewRO = ByteBuffer.allocateDirect(size).order(nativeOrder()).asDoubleBuffer().asReadOnlyBuffer();
|
||||||
|
|
||||||
|
// endianness swapped
|
||||||
|
ByteOrder nonNativeOrder = nativeOrder() == BIG_ENDIAN ? LITTLE_ENDIAN : BIG_ENDIAN;
|
||||||
|
heapByteBufferAsDoubleBufferViewSwap = ByteBuffer.allocate(size).order(nonNativeOrder).asDoubleBuffer();
|
||||||
|
heapByteBufferAsDoubleBufferViewSwapRO = ByteBuffer.allocate(size).order(nonNativeOrder).asDoubleBuffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAsDoubleBufferViewSwap = ByteBuffer.allocateDirect(size).order(nonNativeOrder).asDoubleBuffer();
|
||||||
|
directByteBufferAsDoubleBufferViewSwapRO = ByteBuffer.allocateDirect(size).order(nonNativeOrder).asDoubleBuffer().asReadOnlyBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------- HELPER METHODS
|
||||||
|
|
||||||
|
private int innerLoopGetDouble(DoubleBuffer buf) {
|
||||||
|
int r = 0;
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
r += buf.get(i);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void innerLoopPutDouble(DoubleBuffer buf) {
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
buf.put(i, doubleValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap___
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testHeapBulkPutDouble() {
|
||||||
|
heapDoubleBuffer.put(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testHeapBulkGetDouble() {
|
||||||
|
heapDoubleBuffer.get(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutDouble() {
|
||||||
|
innerLoopPutDouble(heapDoubleBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetDouble() {
|
||||||
|
return innerLoopGetDouble(heapDoubleBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View_Swap_RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testHeapBulkGetDoubleViewSwapRO() {
|
||||||
|
heapByteBufferAsDoubleBufferViewSwapRO.get(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetDoubleViewSwapRO() {
|
||||||
|
return innerLoopGetDouble(heapByteBufferAsDoubleBufferViewSwapRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View_Swap_
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testHeapBulkPutDoubleViewSwap() {
|
||||||
|
heapByteBufferAsDoubleBufferViewSwap.put(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testHeapBulkGetDoubleViewSwap() {
|
||||||
|
heapByteBufferAsDoubleBufferViewSwap.get(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutDoubleViewSwap() {
|
||||||
|
innerLoopPutDouble(heapByteBufferAsDoubleBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetDoubleViewSwap() {
|
||||||
|
return innerLoopGetDouble(heapByteBufferAsDoubleBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View__RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testHeapBulkGetDoubleViewRO() {
|
||||||
|
heapByteBufferAsDoubleBufferViewRO.get(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetDoubleViewRO() {
|
||||||
|
return innerLoopGetDouble(heapByteBufferAsDoubleBufferViewRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View__
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testHeapBulkPutDoubleView() {
|
||||||
|
heapByteBufferAsDoubleBufferView.put(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testHeapBulkGetDoubleView() {
|
||||||
|
heapByteBufferAsDoubleBufferView.get(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutDoubleView() {
|
||||||
|
innerLoopPutDouble(heapByteBufferAsDoubleBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetDoubleView() {
|
||||||
|
return innerLoopGetDouble(heapByteBufferAsDoubleBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View_Swap_RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testDirectBulkGetDoubleViewSwapRO() {
|
||||||
|
directByteBufferAsDoubleBufferViewSwapRO.get(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetDoubleViewSwapRO() {
|
||||||
|
return innerLoopGetDouble(directByteBufferAsDoubleBufferViewSwapRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View_Swap_
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testDirectBulkPutDoubleViewSwap() {
|
||||||
|
directByteBufferAsDoubleBufferViewSwap.put(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testDirectBulkGetDoubleViewSwap() {
|
||||||
|
directByteBufferAsDoubleBufferViewSwap.get(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testDirectLoopPutDoubleViewSwap() {
|
||||||
|
innerLoopPutDouble(directByteBufferAsDoubleBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetDoubleViewSwap() {
|
||||||
|
return innerLoopGetDouble(directByteBufferAsDoubleBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View__RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testDirectBulkGetDoubleViewRO() {
|
||||||
|
directByteBufferAsDoubleBufferViewRO.get(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetDoubleViewRO() {
|
||||||
|
return innerLoopGetDouble(directByteBufferAsDoubleBufferViewRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View__
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testDirectBulkPutDoubleView() {
|
||||||
|
directByteBufferAsDoubleBufferView.put(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double[] testDirectBulkGetDoubleView() {
|
||||||
|
directByteBufferAsDoubleBufferView.get(0, doubleArray);
|
||||||
|
return doubleArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testDirectLoopPutDoubleView() {
|
||||||
|
innerLoopPutDouble(directByteBufferAsDoubleBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetDoubleView() {
|
||||||
|
return innerLoopGetDouble(directByteBufferAsDoubleBufferView);
|
||||||
|
}
|
||||||
|
}
|
289
test/micro/org/openjdk/bench/java/nio/FloatBuffers.java
Normal file
289
test/micro/org/openjdk/bench/java/nio/FloatBuffers.java
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 2021, 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.java.nio;
|
||||||
|
|
||||||
|
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.Param;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
import java.nio.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import static java.nio.ByteOrder.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark for memory access operations on java.nio.Buffer ( and its views )
|
||||||
|
*
|
||||||
|
* A large number of variants are covered. The individual benchmarks conform to
|
||||||
|
* the following convention:
|
||||||
|
* test(Direct|Heap)(Bulk|Loop)(Get|Put)Float(View)?(Swap)?(RO)?
|
||||||
|
*
|
||||||
|
* This allows to easily run a subset of particular interest. For example:
|
||||||
|
* Direct only :- "org.openjdk.bench.java.nio.FloatBuffers.testDirect.*"
|
||||||
|
* Bulk only :- "org.openjdk.bench.java.nio.FloatBuffers.test.*Bulk.*"
|
||||||
|
* Loop Put Swapped Views: -
|
||||||
|
* test(Direct|Heap)(Loop)(Put)Float(View)+(Swap)+"
|
||||||
|
*/
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@State(Scope.Thread)
|
||||||
|
@Fork(3)
|
||||||
|
public class FloatBuffers {
|
||||||
|
|
||||||
|
static final int CARRIER_BYTE_WIDTH = 4;
|
||||||
|
|
||||||
|
@Param({"16", "1024", "131072"})
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
public float floatValue;
|
||||||
|
public float[] floatArray;
|
||||||
|
|
||||||
|
public FloatBuffer heapFloatBuffer;
|
||||||
|
public FloatBuffer heapFloatBufferRO;
|
||||||
|
public FloatBuffer heapByteBufferAsFloatBufferView;
|
||||||
|
public FloatBuffer heapByteBufferAsFloatBufferViewRO;
|
||||||
|
public FloatBuffer heapByteBufferAsFloatBufferViewSwap;
|
||||||
|
public FloatBuffer heapByteBufferAsFloatBufferViewSwapRO;
|
||||||
|
public FloatBuffer directByteBufferAsFloatBufferView;
|
||||||
|
public FloatBuffer directByteBufferAsFloatBufferViewRO;
|
||||||
|
public FloatBuffer directByteBufferAsFloatBufferViewSwap;
|
||||||
|
public FloatBuffer directByteBufferAsFloatBufferViewSwapRO;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
floatArray = new float[size / CARRIER_BYTE_WIDTH];
|
||||||
|
|
||||||
|
// explicitly allocated heap carrier buffer
|
||||||
|
heapFloatBuffer = FloatBuffer.allocate(size / CARRIER_BYTE_WIDTH);
|
||||||
|
heapFloatBufferRO = FloatBuffer.allocate(size / CARRIER_BYTE_WIDTH).asReadOnlyBuffer();
|
||||||
|
|
||||||
|
// ByteBuffer views
|
||||||
|
heapByteBufferAsFloatBufferView = ByteBuffer.allocate(size).order(nativeOrder()).asFloatBuffer();
|
||||||
|
heapByteBufferAsFloatBufferViewRO = ByteBuffer.allocate(size).order(nativeOrder()).asFloatBuffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAsFloatBufferView = ByteBuffer.allocateDirect(size).order(nativeOrder()).asFloatBuffer();
|
||||||
|
directByteBufferAsFloatBufferViewRO = ByteBuffer.allocateDirect(size).order(nativeOrder()).asFloatBuffer().asReadOnlyBuffer();
|
||||||
|
|
||||||
|
// endianness swapped
|
||||||
|
ByteOrder nonNativeOrder = nativeOrder() == BIG_ENDIAN ? LITTLE_ENDIAN : BIG_ENDIAN;
|
||||||
|
heapByteBufferAsFloatBufferViewSwap = ByteBuffer.allocate(size).order(nonNativeOrder).asFloatBuffer();
|
||||||
|
heapByteBufferAsFloatBufferViewSwapRO = ByteBuffer.allocate(size).order(nonNativeOrder).asFloatBuffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAsFloatBufferViewSwap = ByteBuffer.allocateDirect(size).order(nonNativeOrder).asFloatBuffer();
|
||||||
|
directByteBufferAsFloatBufferViewSwapRO = ByteBuffer.allocateDirect(size).order(nonNativeOrder).asFloatBuffer().asReadOnlyBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------- HELPER METHODS
|
||||||
|
|
||||||
|
private int innerLoopGetFloat(FloatBuffer buf) {
|
||||||
|
int r = 0;
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
r += buf.get(i);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void innerLoopPutFloat(FloatBuffer buf) {
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
buf.put(i, floatValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap___
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testHeapBulkPutFloat() {
|
||||||
|
heapFloatBuffer.put(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testHeapBulkGetFloat() {
|
||||||
|
heapFloatBuffer.get(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutFloat() {
|
||||||
|
innerLoopPutFloat(heapFloatBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetFloat() {
|
||||||
|
return innerLoopGetFloat(heapFloatBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View_Swap_RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testHeapBulkGetFloatViewSwapRO() {
|
||||||
|
heapByteBufferAsFloatBufferViewSwapRO.get(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetFloatViewSwapRO() {
|
||||||
|
return innerLoopGetFloat(heapByteBufferAsFloatBufferViewSwapRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View_Swap_
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testHeapBulkPutFloatViewSwap() {
|
||||||
|
heapByteBufferAsFloatBufferViewSwap.put(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testHeapBulkGetFloatViewSwap() {
|
||||||
|
heapByteBufferAsFloatBufferViewSwap.get(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutFloatViewSwap() {
|
||||||
|
innerLoopPutFloat(heapByteBufferAsFloatBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetFloatViewSwap() {
|
||||||
|
return innerLoopGetFloat(heapByteBufferAsFloatBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View__RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testHeapBulkGetFloatViewRO() {
|
||||||
|
heapByteBufferAsFloatBufferViewRO.get(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetFloatViewRO() {
|
||||||
|
return innerLoopGetFloat(heapByteBufferAsFloatBufferViewRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View__
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testHeapBulkPutFloatView() {
|
||||||
|
heapByteBufferAsFloatBufferView.put(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testHeapBulkGetFloatView() {
|
||||||
|
heapByteBufferAsFloatBufferView.get(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutFloatView() {
|
||||||
|
innerLoopPutFloat(heapByteBufferAsFloatBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetFloatView() {
|
||||||
|
return innerLoopGetFloat(heapByteBufferAsFloatBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View_Swap_RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testDirectBulkGetFloatViewSwapRO() {
|
||||||
|
directByteBufferAsFloatBufferViewSwapRO.get(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetFloatViewSwapRO() {
|
||||||
|
return innerLoopGetFloat(directByteBufferAsFloatBufferViewSwapRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View_Swap_
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testDirectBulkPutFloatViewSwap() {
|
||||||
|
directByteBufferAsFloatBufferViewSwap.put(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testDirectBulkGetFloatViewSwap() {
|
||||||
|
directByteBufferAsFloatBufferViewSwap.get(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testDirectLoopPutFloatViewSwap() {
|
||||||
|
innerLoopPutFloat(directByteBufferAsFloatBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetFloatViewSwap() {
|
||||||
|
return innerLoopGetFloat(directByteBufferAsFloatBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View__RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testDirectBulkGetFloatViewRO() {
|
||||||
|
directByteBufferAsFloatBufferViewRO.get(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetFloatViewRO() {
|
||||||
|
return innerLoopGetFloat(directByteBufferAsFloatBufferViewRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View__
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testDirectBulkPutFloatView() {
|
||||||
|
directByteBufferAsFloatBufferView.put(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float[] testDirectBulkGetFloatView() {
|
||||||
|
directByteBufferAsFloatBufferView.get(0, floatArray);
|
||||||
|
return floatArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testDirectLoopPutFloatView() {
|
||||||
|
innerLoopPutFloat(directByteBufferAsFloatBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetFloatView() {
|
||||||
|
return innerLoopGetFloat(directByteBufferAsFloatBufferView);
|
||||||
|
}
|
||||||
|
}
|
289
test/micro/org/openjdk/bench/java/nio/IntBuffers.java
Normal file
289
test/micro/org/openjdk/bench/java/nio/IntBuffers.java
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 2021, 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.java.nio;
|
||||||
|
|
||||||
|
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.Param;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
import java.nio.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import static java.nio.ByteOrder.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark for memory access operations on java.nio.Buffer ( and its views )
|
||||||
|
*
|
||||||
|
* A large number of variants are covered. The individual benchmarks conform to
|
||||||
|
* the following convention:
|
||||||
|
* test(Direct|Heap)(Bulk|Loop)(Get|Put)Int(View)?(Swap)?(RO)?
|
||||||
|
*
|
||||||
|
* This allows to easily run a subset of particular interest. For example:
|
||||||
|
* Direct only :- "org.openjdk.bench.java.nio.IntBuffers.testDirect.*"
|
||||||
|
* Bulk only :- "org.openjdk.bench.java.nio.IntBuffers.test.*Bulk.*"
|
||||||
|
* Loop Put Swapped Views: -
|
||||||
|
* test(Direct|Heap)(Loop)(Put)Int(View)+(Swap)+"
|
||||||
|
*/
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@State(Scope.Thread)
|
||||||
|
@Fork(3)
|
||||||
|
public class IntBuffers {
|
||||||
|
|
||||||
|
static final int CARRIER_BYTE_WIDTH = 4;
|
||||||
|
|
||||||
|
@Param({"16", "1024", "131072"})
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
public int intValue;
|
||||||
|
public int[] intArray;
|
||||||
|
|
||||||
|
public IntBuffer heapIntBuffer;
|
||||||
|
public IntBuffer heapIntBufferRO;
|
||||||
|
public IntBuffer heapByteBufferAsIntBufferView;
|
||||||
|
public IntBuffer heapByteBufferAsIntBufferViewRO;
|
||||||
|
public IntBuffer heapByteBufferAsIntBufferViewSwap;
|
||||||
|
public IntBuffer heapByteBufferAsIntBufferViewSwapRO;
|
||||||
|
public IntBuffer directByteBufferAsIntBufferView;
|
||||||
|
public IntBuffer directByteBufferAsIntBufferViewRO;
|
||||||
|
public IntBuffer directByteBufferAsIntBufferViewSwap;
|
||||||
|
public IntBuffer directByteBufferAsIntBufferViewSwapRO;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
intArray = new int[size / CARRIER_BYTE_WIDTH];
|
||||||
|
|
||||||
|
// explicitly allocated heap carrier buffer
|
||||||
|
heapIntBuffer = IntBuffer.allocate(size / CARRIER_BYTE_WIDTH);
|
||||||
|
heapIntBufferRO = IntBuffer.allocate(size / CARRIER_BYTE_WIDTH).asReadOnlyBuffer();
|
||||||
|
|
||||||
|
// ByteBuffer views
|
||||||
|
heapByteBufferAsIntBufferView = ByteBuffer.allocate(size).order(nativeOrder()).asIntBuffer();
|
||||||
|
heapByteBufferAsIntBufferViewRO = ByteBuffer.allocate(size).order(nativeOrder()).asIntBuffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAsIntBufferView = ByteBuffer.allocateDirect(size).order(nativeOrder()).asIntBuffer();
|
||||||
|
directByteBufferAsIntBufferViewRO = ByteBuffer.allocateDirect(size).order(nativeOrder()).asIntBuffer().asReadOnlyBuffer();
|
||||||
|
|
||||||
|
// endianness swapped
|
||||||
|
ByteOrder nonNativeOrder = nativeOrder() == BIG_ENDIAN ? LITTLE_ENDIAN : BIG_ENDIAN;
|
||||||
|
heapByteBufferAsIntBufferViewSwap = ByteBuffer.allocate(size).order(nonNativeOrder).asIntBuffer();
|
||||||
|
heapByteBufferAsIntBufferViewSwapRO = ByteBuffer.allocate(size).order(nonNativeOrder).asIntBuffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAsIntBufferViewSwap = ByteBuffer.allocateDirect(size).order(nonNativeOrder).asIntBuffer();
|
||||||
|
directByteBufferAsIntBufferViewSwapRO = ByteBuffer.allocateDirect(size).order(nonNativeOrder).asIntBuffer().asReadOnlyBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------- HELPER METHODS
|
||||||
|
|
||||||
|
private int innerLoopGetInt(IntBuffer buf) {
|
||||||
|
int r = 0;
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
r += buf.get(i);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void innerLoopPutInt(IntBuffer buf) {
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
buf.put(i, intValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap___
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testHeapBulkPutInt() {
|
||||||
|
heapIntBuffer.put(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testHeapBulkGetInt() {
|
||||||
|
heapIntBuffer.get(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutInt() {
|
||||||
|
innerLoopPutInt(heapIntBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetInt() {
|
||||||
|
return innerLoopGetInt(heapIntBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View_Swap_RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testHeapBulkGetIntViewSwapRO() {
|
||||||
|
heapByteBufferAsIntBufferViewSwapRO.get(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetIntViewSwapRO() {
|
||||||
|
return innerLoopGetInt(heapByteBufferAsIntBufferViewSwapRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View_Swap_
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testHeapBulkPutIntViewSwap() {
|
||||||
|
heapByteBufferAsIntBufferViewSwap.put(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testHeapBulkGetIntViewSwap() {
|
||||||
|
heapByteBufferAsIntBufferViewSwap.get(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutIntViewSwap() {
|
||||||
|
innerLoopPutInt(heapByteBufferAsIntBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetIntViewSwap() {
|
||||||
|
return innerLoopGetInt(heapByteBufferAsIntBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View__RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testHeapBulkGetIntViewRO() {
|
||||||
|
heapByteBufferAsIntBufferViewRO.get(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetIntViewRO() {
|
||||||
|
return innerLoopGetInt(heapByteBufferAsIntBufferViewRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View__
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testHeapBulkPutIntView() {
|
||||||
|
heapByteBufferAsIntBufferView.put(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testHeapBulkGetIntView() {
|
||||||
|
heapByteBufferAsIntBufferView.get(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutIntView() {
|
||||||
|
innerLoopPutInt(heapByteBufferAsIntBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetIntView() {
|
||||||
|
return innerLoopGetInt(heapByteBufferAsIntBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View_Swap_RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testDirectBulkGetIntViewSwapRO() {
|
||||||
|
directByteBufferAsIntBufferViewSwapRO.get(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetIntViewSwapRO() {
|
||||||
|
return innerLoopGetInt(directByteBufferAsIntBufferViewSwapRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View_Swap_
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testDirectBulkPutIntViewSwap() {
|
||||||
|
directByteBufferAsIntBufferViewSwap.put(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testDirectBulkGetIntViewSwap() {
|
||||||
|
directByteBufferAsIntBufferViewSwap.get(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testDirectLoopPutIntViewSwap() {
|
||||||
|
innerLoopPutInt(directByteBufferAsIntBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetIntViewSwap() {
|
||||||
|
return innerLoopGetInt(directByteBufferAsIntBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View__RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testDirectBulkGetIntViewRO() {
|
||||||
|
directByteBufferAsIntBufferViewRO.get(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetIntViewRO() {
|
||||||
|
return innerLoopGetInt(directByteBufferAsIntBufferViewRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View__
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testDirectBulkPutIntView() {
|
||||||
|
directByteBufferAsIntBufferView.put(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int[] testDirectBulkGetIntView() {
|
||||||
|
directByteBufferAsIntBufferView.get(0, intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testDirectLoopPutIntView() {
|
||||||
|
innerLoopPutInt(directByteBufferAsIntBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetIntView() {
|
||||||
|
return innerLoopGetInt(directByteBufferAsIntBufferView);
|
||||||
|
}
|
||||||
|
}
|
289
test/micro/org/openjdk/bench/java/nio/LongBuffers.java
Normal file
289
test/micro/org/openjdk/bench/java/nio/LongBuffers.java
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 2021, 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.java.nio;
|
||||||
|
|
||||||
|
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.Param;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
import java.nio.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import static java.nio.ByteOrder.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark for memory access operations on java.nio.Buffer ( and its views )
|
||||||
|
*
|
||||||
|
* A large number of variants are covered. The individual benchmarks conform to
|
||||||
|
* the following convention:
|
||||||
|
* test(Direct|Heap)(Bulk|Loop)(Get|Put)Long(View)?(Swap)?(RO)?
|
||||||
|
*
|
||||||
|
* This allows to easily run a subset of particular interest. For example:
|
||||||
|
* Direct only :- "org.openjdk.bench.java.nio.LongBuffers.testDirect.*"
|
||||||
|
* Bulk only :- "org.openjdk.bench.java.nio.LongBuffers.test.*Bulk.*"
|
||||||
|
* Loop Put Swapped Views: -
|
||||||
|
* test(Direct|Heap)(Loop)(Put)Long(View)+(Swap)+"
|
||||||
|
*/
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@State(Scope.Thread)
|
||||||
|
@Fork(3)
|
||||||
|
public class LongBuffers {
|
||||||
|
|
||||||
|
static final int CARRIER_BYTE_WIDTH = 8;
|
||||||
|
|
||||||
|
@Param({"16", "1024", "131072"})
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
public long longValue;
|
||||||
|
public long[] longArray;
|
||||||
|
|
||||||
|
public LongBuffer heapLongBuffer;
|
||||||
|
public LongBuffer heapLongBufferRO;
|
||||||
|
public LongBuffer heapByteBufferAsLongBufferView;
|
||||||
|
public LongBuffer heapByteBufferAsLongBufferViewRO;
|
||||||
|
public LongBuffer heapByteBufferAsLongBufferViewSwap;
|
||||||
|
public LongBuffer heapByteBufferAsLongBufferViewSwapRO;
|
||||||
|
public LongBuffer directByteBufferAsLongBufferView;
|
||||||
|
public LongBuffer directByteBufferAsLongBufferViewRO;
|
||||||
|
public LongBuffer directByteBufferAsLongBufferViewSwap;
|
||||||
|
public LongBuffer directByteBufferAsLongBufferViewSwapRO;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
longArray = new long[size / CARRIER_BYTE_WIDTH];
|
||||||
|
|
||||||
|
// explicitly allocated heap carrier buffer
|
||||||
|
heapLongBuffer = LongBuffer.allocate(size / CARRIER_BYTE_WIDTH);
|
||||||
|
heapLongBufferRO = LongBuffer.allocate(size / CARRIER_BYTE_WIDTH).asReadOnlyBuffer();
|
||||||
|
|
||||||
|
// ByteBuffer views
|
||||||
|
heapByteBufferAsLongBufferView = ByteBuffer.allocate(size).order(nativeOrder()).asLongBuffer();
|
||||||
|
heapByteBufferAsLongBufferViewRO = ByteBuffer.allocate(size).order(nativeOrder()).asLongBuffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAsLongBufferView = ByteBuffer.allocateDirect(size).order(nativeOrder()).asLongBuffer();
|
||||||
|
directByteBufferAsLongBufferViewRO = ByteBuffer.allocateDirect(size).order(nativeOrder()).asLongBuffer().asReadOnlyBuffer();
|
||||||
|
|
||||||
|
// endianness swapped
|
||||||
|
ByteOrder nonNativeOrder = nativeOrder() == BIG_ENDIAN ? LITTLE_ENDIAN : BIG_ENDIAN;
|
||||||
|
heapByteBufferAsLongBufferViewSwap = ByteBuffer.allocate(size).order(nonNativeOrder).asLongBuffer();
|
||||||
|
heapByteBufferAsLongBufferViewSwapRO = ByteBuffer.allocate(size).order(nonNativeOrder).asLongBuffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAsLongBufferViewSwap = ByteBuffer.allocateDirect(size).order(nonNativeOrder).asLongBuffer();
|
||||||
|
directByteBufferAsLongBufferViewSwapRO = ByteBuffer.allocateDirect(size).order(nonNativeOrder).asLongBuffer().asReadOnlyBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------- HELPER METHODS
|
||||||
|
|
||||||
|
private int innerLoopGetLong(LongBuffer buf) {
|
||||||
|
int r = 0;
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
r += buf.get(i);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void innerLoopPutLong(LongBuffer buf) {
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
buf.put(i, longValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap___
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testHeapBulkPutLong() {
|
||||||
|
heapLongBuffer.put(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testHeapBulkGetLong() {
|
||||||
|
heapLongBuffer.get(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutLong() {
|
||||||
|
innerLoopPutLong(heapLongBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetLong() {
|
||||||
|
return innerLoopGetLong(heapLongBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View_Swap_RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testHeapBulkGetLongViewSwapRO() {
|
||||||
|
heapByteBufferAsLongBufferViewSwapRO.get(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetLongViewSwapRO() {
|
||||||
|
return innerLoopGetLong(heapByteBufferAsLongBufferViewSwapRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View_Swap_
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testHeapBulkPutLongViewSwap() {
|
||||||
|
heapByteBufferAsLongBufferViewSwap.put(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testHeapBulkGetLongViewSwap() {
|
||||||
|
heapByteBufferAsLongBufferViewSwap.get(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutLongViewSwap() {
|
||||||
|
innerLoopPutLong(heapByteBufferAsLongBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetLongViewSwap() {
|
||||||
|
return innerLoopGetLong(heapByteBufferAsLongBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View__RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testHeapBulkGetLongViewRO() {
|
||||||
|
heapByteBufferAsLongBufferViewRO.get(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetLongViewRO() {
|
||||||
|
return innerLoopGetLong(heapByteBufferAsLongBufferViewRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View__
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testHeapBulkPutLongView() {
|
||||||
|
heapByteBufferAsLongBufferView.put(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testHeapBulkGetLongView() {
|
||||||
|
heapByteBufferAsLongBufferView.get(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutLongView() {
|
||||||
|
innerLoopPutLong(heapByteBufferAsLongBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetLongView() {
|
||||||
|
return innerLoopGetLong(heapByteBufferAsLongBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View_Swap_RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testDirectBulkGetLongViewSwapRO() {
|
||||||
|
directByteBufferAsLongBufferViewSwapRO.get(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetLongViewSwapRO() {
|
||||||
|
return innerLoopGetLong(directByteBufferAsLongBufferViewSwapRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View_Swap_
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testDirectBulkPutLongViewSwap() {
|
||||||
|
directByteBufferAsLongBufferViewSwap.put(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testDirectBulkGetLongViewSwap() {
|
||||||
|
directByteBufferAsLongBufferViewSwap.get(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testDirectLoopPutLongViewSwap() {
|
||||||
|
innerLoopPutLong(directByteBufferAsLongBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetLongViewSwap() {
|
||||||
|
return innerLoopGetLong(directByteBufferAsLongBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View__RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testDirectBulkGetLongViewRO() {
|
||||||
|
directByteBufferAsLongBufferViewRO.get(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetLongViewRO() {
|
||||||
|
return innerLoopGetLong(directByteBufferAsLongBufferViewRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View__
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testDirectBulkPutLongView() {
|
||||||
|
directByteBufferAsLongBufferView.put(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long[] testDirectBulkGetLongView() {
|
||||||
|
directByteBufferAsLongBufferView.get(0, longArray);
|
||||||
|
return longArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testDirectLoopPutLongView() {
|
||||||
|
innerLoopPutLong(directByteBufferAsLongBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetLongView() {
|
||||||
|
return innerLoopGetLong(directByteBufferAsLongBufferView);
|
||||||
|
}
|
||||||
|
}
|
289
test/micro/org/openjdk/bench/java/nio/ShortBuffers.java
Normal file
289
test/micro/org/openjdk/bench/java/nio/ShortBuffers.java
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 2021, 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.java.nio;
|
||||||
|
|
||||||
|
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.Param;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
import java.nio.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import static java.nio.ByteOrder.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark for memory access operations on java.nio.Buffer ( and its views )
|
||||||
|
*
|
||||||
|
* A large number of variants are covered. The individual benchmarks conform to
|
||||||
|
* the following convention:
|
||||||
|
* test(Direct|Heap)(Bulk|Loop)(Get|Put)Short(View)?(Swap)?(RO)?
|
||||||
|
*
|
||||||
|
* This allows to easily run a subset of particular interest. For example:
|
||||||
|
* Direct only :- "org.openjdk.bench.java.nio.ShortBuffers.testDirect.*"
|
||||||
|
* Bulk only :- "org.openjdk.bench.java.nio.ShortBuffers.test.*Bulk.*"
|
||||||
|
* Loop Put Swapped Views: -
|
||||||
|
* test(Direct|Heap)(Loop)(Put)Short(View)+(Swap)+"
|
||||||
|
*/
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@State(Scope.Thread)
|
||||||
|
@Fork(3)
|
||||||
|
public class ShortBuffers {
|
||||||
|
|
||||||
|
static final int CARRIER_BYTE_WIDTH = 2;
|
||||||
|
|
||||||
|
@Param({"16", "1024", "131072"})
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
public short shortValue;
|
||||||
|
public short[] shortArray;
|
||||||
|
|
||||||
|
public ShortBuffer heapShortBuffer;
|
||||||
|
public ShortBuffer heapShortBufferRO;
|
||||||
|
public ShortBuffer heapByteBufferAsShortBufferView;
|
||||||
|
public ShortBuffer heapByteBufferAsShortBufferViewRO;
|
||||||
|
public ShortBuffer heapByteBufferAsShortBufferViewSwap;
|
||||||
|
public ShortBuffer heapByteBufferAsShortBufferViewSwapRO;
|
||||||
|
public ShortBuffer directByteBufferAsShortBufferView;
|
||||||
|
public ShortBuffer directByteBufferAsShortBufferViewRO;
|
||||||
|
public ShortBuffer directByteBufferAsShortBufferViewSwap;
|
||||||
|
public ShortBuffer directByteBufferAsShortBufferViewSwapRO;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
shortArray = new short[size / CARRIER_BYTE_WIDTH];
|
||||||
|
|
||||||
|
// explicitly allocated heap carrier buffer
|
||||||
|
heapShortBuffer = ShortBuffer.allocate(size / CARRIER_BYTE_WIDTH);
|
||||||
|
heapShortBufferRO = ShortBuffer.allocate(size / CARRIER_BYTE_WIDTH).asReadOnlyBuffer();
|
||||||
|
|
||||||
|
// ByteBuffer views
|
||||||
|
heapByteBufferAsShortBufferView = ByteBuffer.allocate(size).order(nativeOrder()).asShortBuffer();
|
||||||
|
heapByteBufferAsShortBufferViewRO = ByteBuffer.allocate(size).order(nativeOrder()).asShortBuffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAsShortBufferView = ByteBuffer.allocateDirect(size).order(nativeOrder()).asShortBuffer();
|
||||||
|
directByteBufferAsShortBufferViewRO = ByteBuffer.allocateDirect(size).order(nativeOrder()).asShortBuffer().asReadOnlyBuffer();
|
||||||
|
|
||||||
|
// endianness swapped
|
||||||
|
ByteOrder nonNativeOrder = nativeOrder() == BIG_ENDIAN ? LITTLE_ENDIAN : BIG_ENDIAN;
|
||||||
|
heapByteBufferAsShortBufferViewSwap = ByteBuffer.allocate(size).order(nonNativeOrder).asShortBuffer();
|
||||||
|
heapByteBufferAsShortBufferViewSwapRO = ByteBuffer.allocate(size).order(nonNativeOrder).asShortBuffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAsShortBufferViewSwap = ByteBuffer.allocateDirect(size).order(nonNativeOrder).asShortBuffer();
|
||||||
|
directByteBufferAsShortBufferViewSwapRO = ByteBuffer.allocateDirect(size).order(nonNativeOrder).asShortBuffer().asReadOnlyBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------- HELPER METHODS
|
||||||
|
|
||||||
|
private int innerLoopGetShort(ShortBuffer buf) {
|
||||||
|
int r = 0;
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
r += buf.get(i);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void innerLoopPutShort(ShortBuffer buf) {
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
buf.put(i, shortValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap___
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testHeapBulkPutShort() {
|
||||||
|
heapShortBuffer.put(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testHeapBulkGetShort() {
|
||||||
|
heapShortBuffer.get(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutShort() {
|
||||||
|
innerLoopPutShort(heapShortBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetShort() {
|
||||||
|
return innerLoopGetShort(heapShortBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View_Swap_RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testHeapBulkGetShortViewSwapRO() {
|
||||||
|
heapByteBufferAsShortBufferViewSwapRO.get(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetShortViewSwapRO() {
|
||||||
|
return innerLoopGetShort(heapByteBufferAsShortBufferViewSwapRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View_Swap_
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testHeapBulkPutShortViewSwap() {
|
||||||
|
heapByteBufferAsShortBufferViewSwap.put(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testHeapBulkGetShortViewSwap() {
|
||||||
|
heapByteBufferAsShortBufferViewSwap.get(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutShortViewSwap() {
|
||||||
|
innerLoopPutShort(heapByteBufferAsShortBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetShortViewSwap() {
|
||||||
|
return innerLoopGetShort(heapByteBufferAsShortBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View__RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testHeapBulkGetShortViewRO() {
|
||||||
|
heapByteBufferAsShortBufferViewRO.get(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetShortViewRO() {
|
||||||
|
return innerLoopGetShort(heapByteBufferAsShortBufferViewRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Heap_View__
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testHeapBulkPutShortView() {
|
||||||
|
heapByteBufferAsShortBufferView.put(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testHeapBulkGetShortView() {
|
||||||
|
heapByteBufferAsShortBufferView.get(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testHeapLoopPutShortView() {
|
||||||
|
innerLoopPutShort(heapByteBufferAsShortBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testHeapLoopGetShortView() {
|
||||||
|
return innerLoopGetShort(heapByteBufferAsShortBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View_Swap_RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testDirectBulkGetShortViewSwapRO() {
|
||||||
|
directByteBufferAsShortBufferViewSwapRO.get(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetShortViewSwapRO() {
|
||||||
|
return innerLoopGetShort(directByteBufferAsShortBufferViewSwapRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View_Swap_
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testDirectBulkPutShortViewSwap() {
|
||||||
|
directByteBufferAsShortBufferViewSwap.put(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testDirectBulkGetShortViewSwap() {
|
||||||
|
directByteBufferAsShortBufferViewSwap.get(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testDirectLoopPutShortViewSwap() {
|
||||||
|
innerLoopPutShort(directByteBufferAsShortBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetShortViewSwap() {
|
||||||
|
return innerLoopGetShort(directByteBufferAsShortBufferViewSwap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View__RO
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testDirectBulkGetShortViewRO() {
|
||||||
|
directByteBufferAsShortBufferViewRO.get(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetShortViewRO() {
|
||||||
|
return innerLoopGetShort(directByteBufferAsShortBufferViewRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Direct_View__
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testDirectBulkPutShortView() {
|
||||||
|
directByteBufferAsShortBufferView.put(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public short[] testDirectBulkGetShortView() {
|
||||||
|
directByteBufferAsShortBufferView.get(0, shortArray);
|
||||||
|
return shortArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void testDirectLoopPutShortView() {
|
||||||
|
innerLoopPutShort(directByteBufferAsShortBufferView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int testDirectLoopGetShortView() {
|
||||||
|
return innerLoopGetShort(directByteBufferAsShortBufferView);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 2021, 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. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#warn This file is preprocessed before being compiled
|
||||||
|
|
||||||
|
class XXX {
|
||||||
|
#begin
|
||||||
|
|
||||||
|
// -- $Ms$_{#if[view]?View}_$SWAP$_$RO$
|
||||||
|
#if[!RO]
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public $type$[] test$Ms$BulkPut$Type${#if[view]?View}$SWAP$$RO$() {
|
||||||
|
$ms${#if[view]?ByteBufferAs}$Type$Buffer{#if[view]?View}$SWAP$$RO$.put(0, $type$Array);
|
||||||
|
return $type$Array;
|
||||||
|
}
|
||||||
|
#end[RO]
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public $type$[] test$Ms$BulkGet$Type${#if[view]?View}$SWAP$$RO$() {
|
||||||
|
$ms${#if[view]?ByteBufferAs}$Type$Buffer{#if[view]?View}$SWAP$$RO$.get(0, $type$Array);
|
||||||
|
return $type$Array;
|
||||||
|
}
|
||||||
|
#if[!byte]
|
||||||
|
#if[!RO]
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void test$Ms$LoopPut$Type${#if[view]?View$SWAP$}$RO$() {
|
||||||
|
innerLoopPut$Type$($ms${#if[view]?ByteBufferAs}$Type$Buffer{#if[view]?View}$SWAP$$RO$);
|
||||||
|
}
|
||||||
|
#end[RO]
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int test$Ms$LoopGet$Type${#if[view]?View}$SWAP$$RO$() {
|
||||||
|
return innerLoopGet$Type$($ms${#if[view]?ByteBufferAs}$Type$Buffer{#if[view]?View}$SWAP$$RO$);
|
||||||
|
}
|
||||||
|
#end[byte]
|
||||||
|
#end
|
||||||
|
}
|
149
test/micro/org/openjdk/bench/java/nio/X-Buffers.java.template
Normal file
149
test/micro/org/openjdk/bench/java/nio/X-Buffers.java.template
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 2021, 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.java.nio;
|
||||||
|
|
||||||
|
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.Param;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
import java.nio.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import static java.nio.ByteOrder.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark for memory access operations on java.nio.Buffer ( and its views )
|
||||||
|
*
|
||||||
|
* A large number of variants are covered. The individual benchmarks conform to
|
||||||
|
* the following convention:
|
||||||
|
#if[byte]
|
||||||
|
* test(Direct|Heap)(Bulk|Loop)(Get|Put)(Byte|Char|Short|Int|Long|Float|Double)(Swap)?(RO)?
|
||||||
|
#else[byte]
|
||||||
|
* test(Direct|Heap)(Bulk|Loop)(Get|Put)$Type$(View)?(Swap)?(RO)?
|
||||||
|
#end[byte]
|
||||||
|
*
|
||||||
|
* This allows to easily run a subset of particular interest. For example:
|
||||||
|
* Direct only :- "org.openjdk.bench.java.nio.$Type$Buffers.testDirect.*"
|
||||||
|
* Bulk only :- "org.openjdk.bench.java.nio.$Type$Buffers.test.*Bulk.*"
|
||||||
|
* Loop Put Swapped Views: -
|
||||||
|
* test(Direct|Heap)(Loop)(Put)$Type$(View)+(Swap)+"
|
||||||
|
*/
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@State(Scope.Thread)
|
||||||
|
@Fork(3)
|
||||||
|
public class $Type$Buffers {
|
||||||
|
|
||||||
|
static final int CARRIER_BYTE_WIDTH = $CarrierBW$;
|
||||||
|
|
||||||
|
@Param({"16", "1024", "131072"})
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
public $type$ $type$Value;
|
||||||
|
#if[byte]
|
||||||
|
public char charValue;
|
||||||
|
public short shortValue;
|
||||||
|
public int intValue;
|
||||||
|
public long longValue;
|
||||||
|
public float floatValue;
|
||||||
|
public double doubleValue;
|
||||||
|
#end[byte]
|
||||||
|
public $type$[] $type$Array;
|
||||||
|
|
||||||
|
public $Type$Buffer heap$Type$Buffer;
|
||||||
|
public $Type$Buffer heap$Type$BufferRO;
|
||||||
|
#if[byte]
|
||||||
|
public ByteBuffer directByteBuffer;
|
||||||
|
public ByteBuffer directByteBufferRO;
|
||||||
|
public ByteBuffer heapByteBufferSwap;
|
||||||
|
public ByteBuffer heapByteBufferSwapRO;
|
||||||
|
public ByteBuffer directByteBufferSwap;
|
||||||
|
public ByteBuffer directByteBufferSwapRO;
|
||||||
|
#else[byte]
|
||||||
|
public $Type$Buffer heapByteBufferAs$Type$BufferView;
|
||||||
|
public $Type$Buffer heapByteBufferAs$Type$BufferViewRO;
|
||||||
|
public $Type$Buffer heapByteBufferAs$Type$BufferViewSwap;
|
||||||
|
public $Type$Buffer heapByteBufferAs$Type$BufferViewSwapRO;
|
||||||
|
public $Type$Buffer directByteBufferAs$Type$BufferView;
|
||||||
|
public $Type$Buffer directByteBufferAs$Type$BufferViewRO;
|
||||||
|
public $Type$Buffer directByteBufferAs$Type$BufferViewSwap;
|
||||||
|
public $Type$Buffer directByteBufferAs$Type$BufferViewSwapRO;
|
||||||
|
#end[byte]
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
$type$Array = new $type$[size / CARRIER_BYTE_WIDTH];
|
||||||
|
|
||||||
|
// explicitly allocated heap carrier buffer
|
||||||
|
heap$Type$Buffer = $Type$Buffer.allocate(size / CARRIER_BYTE_WIDTH);
|
||||||
|
heap$Type$BufferRO = $Type$Buffer.allocate(size / CARRIER_BYTE_WIDTH).asReadOnlyBuffer();
|
||||||
|
#if[byte]
|
||||||
|
|
||||||
|
heapByteBufferSwap = ByteBuffer.allocate(size / CARRIER_BYTE_WIDTH).order(LITTLE_ENDIAN);
|
||||||
|
heapByteBufferSwapRO = ByteBuffer.allocate(size / CARRIER_BYTE_WIDTH).order(LITTLE_ENDIAN).asReadOnlyBuffer();
|
||||||
|
directByteBuffer = ByteBuffer.allocateDirect(size / CARRIER_BYTE_WIDTH);
|
||||||
|
directByteBufferRO = ByteBuffer.allocateDirect(size / CARRIER_BYTE_WIDTH).asReadOnlyBuffer();
|
||||||
|
directByteBufferSwap = ByteBuffer.allocateDirect(size / CARRIER_BYTE_WIDTH).order(LITTLE_ENDIAN);
|
||||||
|
directByteBufferSwapRO = ByteBuffer.allocateDirect(size / CARRIER_BYTE_WIDTH).order(LITTLE_ENDIAN).asReadOnlyBuffer();
|
||||||
|
#else[byte]
|
||||||
|
|
||||||
|
// ByteBuffer views
|
||||||
|
heapByteBufferAs$Type$BufferView = ByteBuffer.allocate(size).order(nativeOrder()).as$Type$Buffer();
|
||||||
|
heapByteBufferAs$Type$BufferViewRO = ByteBuffer.allocate(size).order(nativeOrder()).as$Type$Buffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAs$Type$BufferView = ByteBuffer.allocateDirect(size).order(nativeOrder()).as$Type$Buffer();
|
||||||
|
directByteBufferAs$Type$BufferViewRO = ByteBuffer.allocateDirect(size).order(nativeOrder()).as$Type$Buffer().asReadOnlyBuffer();
|
||||||
|
|
||||||
|
// endianness swapped
|
||||||
|
ByteOrder nonNativeOrder = nativeOrder() == BIG_ENDIAN ? LITTLE_ENDIAN : BIG_ENDIAN;
|
||||||
|
heapByteBufferAs$Type$BufferViewSwap = ByteBuffer.allocate(size).order(nonNativeOrder).as$Type$Buffer();
|
||||||
|
heapByteBufferAs$Type$BufferViewSwapRO = ByteBuffer.allocate(size).order(nonNativeOrder).as$Type$Buffer().asReadOnlyBuffer();
|
||||||
|
directByteBufferAs$Type$BufferViewSwap = ByteBuffer.allocateDirect(size).order(nonNativeOrder).as$Type$Buffer();
|
||||||
|
directByteBufferAs$Type$BufferViewSwapRO = ByteBuffer.allocateDirect(size).order(nonNativeOrder).as$Type$Buffer().asReadOnlyBuffer();
|
||||||
|
#end[byte]
|
||||||
|
}
|
||||||
|
|
||||||
|
#if[!byte]
|
||||||
|
// ---------------- HELPER METHODS
|
||||||
|
|
||||||
|
private int innerLoopGet$Type$($Type$Buffer buf) {
|
||||||
|
int r = 0;
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
r += buf.get(i);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void innerLoopPut$Type$($Type$Buffer buf) {
|
||||||
|
for (int i = 0; i < buf.capacity(); i++) {
|
||||||
|
buf.put(i, $type$Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#end[byte]
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, 2021, 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. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#warn This file is preprocessed before being compiled
|
||||||
|
|
||||||
|
class XXX {
|
||||||
|
#begin
|
||||||
|
|
||||||
|
// -- $Ms$_$Type$_$SWAP$_$RO$
|
||||||
|
#if[!RO]
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void test$Ms$LoopPut$Type$$SWAP$$RO$() {
|
||||||
|
for (int i = 0; i < $ms$ByteBuffer$SWAP$$RO$.capacity(); i+=$CarrierBW$) {
|
||||||
|
$ms$ByteBuffer$SWAP$$RO$.put{#if[!byte]?$Type$}(i, $type$Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#end[RO]
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int test$Ms$LoopGet$Type$$SWAP$$RO$() {
|
||||||
|
int r = 0;
|
||||||
|
for (int i = 0; i < $ms$ByteBuffer$SWAP$$RO$.capacity(); i+=$CarrierBW$) {
|
||||||
|
r += $ms$ByteBuffer$SWAP$$RO$.get{#if[!byte]?$Type$}(i);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
}
|
84
test/micro/org/openjdk/bench/java/nio/genBuffers.sh
Normal file
84
test/micro/org/openjdk/bench/java/nio/genBuffers.sh
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020, 2021, 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
javac -d . ../../../../../../../make/jdk/src/classes/build/tools/spp/Spp.java
|
||||||
|
|
||||||
|
genBin() {
|
||||||
|
for MS in "Heap" "Direct"
|
||||||
|
do
|
||||||
|
for SWAP in "Swap" ""
|
||||||
|
do
|
||||||
|
for RO in "RO" ""
|
||||||
|
do
|
||||||
|
extraArgs=""
|
||||||
|
if [ "$RO" == "RO" ] ; then
|
||||||
|
extraArgs="-KRO"
|
||||||
|
fi
|
||||||
|
java build.tools.spp.Spp -be -nel -K$1 -Dtype=$1 -DType=$2 -DFulltype=$3 \
|
||||||
|
$extraArgs \
|
||||||
|
-Kview \
|
||||||
|
-DMs=$MS \
|
||||||
|
-Dms=`echo "$MS" | awk '{print tolower($0)}'` \
|
||||||
|
-DSWAP=$SWAP \
|
||||||
|
-DRO=$RO \
|
||||||
|
-DCarrierBW=$4 \
|
||||||
|
-i$5 \
|
||||||
|
-o$out
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
gen() {
|
||||||
|
out=$2Buffers.java
|
||||||
|
rm -f $out
|
||||||
|
java build.tools.spp.Spp -be -nel -K$1 -Dtype=$1 -DType=$2 -DFulltype=$3 \
|
||||||
|
-DCarrierBW=$4 -iX-Buffers.java.template -o$out
|
||||||
|
|
||||||
|
java build.tools.spp.Spp -be -nel -K$1 -Dtype=$1 -DType=$2 -DFulltype=$3 \
|
||||||
|
-DMs=Heap -Dms=heap -DSWAP="" -DRO="" -iX-Buffers-bin.java.template -o$out
|
||||||
|
|
||||||
|
if [ "$1" == "byte" ] ; then
|
||||||
|
genBin $1 $2 $3 $4 X-ByteBuffers-bin.java.template
|
||||||
|
genBin char Char Character 2 X-ByteBuffers-bin.java.template
|
||||||
|
genBin short Short Short 2 X-ByteBuffers-bin.java.template
|
||||||
|
genBin int Int Integer 4 X-ByteBuffers-bin.java.template
|
||||||
|
genBin long Long Long 8 X-ByteBuffers-bin.java.template
|
||||||
|
genBin float Float Float 4 X-ByteBuffers-bin.java.template
|
||||||
|
genBin double Double Double 8 X-ByteBuffers-bin.java.template
|
||||||
|
else
|
||||||
|
genBin $1 $2 $3 $4 X-Buffers-bin.java.template
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "}\n" >> $out
|
||||||
|
}
|
||||||
|
|
||||||
|
gen byte Byte Byte 1
|
||||||
|
gen char Char Character 2
|
||||||
|
gen short Short Short 2
|
||||||
|
gen int Int Integer 4
|
||||||
|
gen long Long Long 8
|
||||||
|
gen float Float Float 4
|
||||||
|
gen double Double Double 8
|
Loading…
Add table
Add a link
Reference in a new issue