Add JMH benchmark for the square-and-add kernel
This commit is contained in:
63
jmh/src/main/java/com/ankurm/vectorapi/VectorBench.java
Normal file
63
jmh/src/main/java/com/ankurm/vectorapi/VectorBench.java
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package com.ankurm.vectorapi;
|
||||||
|
|
||||||
|
import jdk.incubator.vector.*;
|
||||||
|
import org.openjdk.jmh.annotations.*;
|
||||||
|
import org.openjdk.jmh.infra.Blackhole;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@State(Scope.Thread)
|
||||||
|
@Warmup(iterations = 5, time = 1)
|
||||||
|
@Measurement(iterations = 5, time = 1)
|
||||||
|
@Fork(1)
|
||||||
|
public class VectorBench {
|
||||||
|
static final VectorSpecies<Float> SP = FloatVector.SPECIES_PREFERRED;
|
||||||
|
float[] a, b, c;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
int n = 8192;
|
||||||
|
a = new float[n]; b = new float[n]; c = new float[n];
|
||||||
|
Random r = new Random(42);
|
||||||
|
for (int i = 0; i < n; i++) { a[i] = r.nextFloat(); b[i] = r.nextFloat(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// The result array is written, then handed to JMH's Blackhole so neither the
|
||||||
|
// stores nor the arithmetic can be eliminated as dead code.
|
||||||
|
@Benchmark
|
||||||
|
public void scalar(Blackhole bh) {
|
||||||
|
for (int i = 0; i < a.length; i++) c[i] = -(a[i]*a[i] + b[i]*b[i]);
|
||||||
|
bh.consume(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void vector(Blackhole bh) {
|
||||||
|
int i = 0, bound = SP.loopBound(a.length);
|
||||||
|
for (; i < bound; i += SP.length()) {
|
||||||
|
var va = FloatVector.fromArray(SP, a, i);
|
||||||
|
var vb = FloatVector.fromArray(SP, b, i);
|
||||||
|
va.mul(va).add(vb.mul(vb)).neg().intoArray(c, i);
|
||||||
|
}
|
||||||
|
for (; i < a.length; i++) c[i] = -(a[i]*a[i] + b[i]*b[i]);
|
||||||
|
bh.consume(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same kernel, but returning a value derived from the output. Returned values
|
||||||
|
// are consumed by JMH automatically. Note what this costs: the checksum loop is
|
||||||
|
// itself measured, which is why this variant reports ~9x the time of vector().
|
||||||
|
@Benchmark
|
||||||
|
public float vectorChecksum() {
|
||||||
|
int i = 0, bound = SP.loopBound(a.length);
|
||||||
|
for (; i < bound; i += SP.length()) {
|
||||||
|
var va = FloatVector.fromArray(SP, a, i);
|
||||||
|
var vb = FloatVector.fromArray(SP, b, i);
|
||||||
|
va.mul(va).add(vb.mul(vb)).neg().intoArray(c, i);
|
||||||
|
}
|
||||||
|
for (; i < a.length; i++) c[i] = -(a[i]*a[i] + b[i]*b[i]);
|
||||||
|
float sum = 0;
|
||||||
|
for (float v : c) sum += v;
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user