diff --git a/jmh/src/main/java/com/ankurm/vectorapi/BrightnessBench.java b/jmh/src/main/java/com/ankurm/vectorapi/BrightnessBench.java new file mode 100644 index 0000000..e66a16f --- /dev/null +++ b/jmh/src/main/java/com/ankurm/vectorapi/BrightnessBench.java @@ -0,0 +1,55 @@ +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; + +/** JMH version of the image brightness + clamp kernel. */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(1) +public class BrightnessBench { + static final VectorSpecies SP = FloatVector.SPECIES_PREFERRED; + float[] in, out; + float gain = 1.4f, bias = 12f; + + @Setup + public void setup() { + in = new float[8192]; out = new float[8192]; + Random r = new Random(11); + for (int i = 0; i < in.length; i++) in[i] = r.nextFloat() * 300f - 20f; + } + + @Benchmark + public void scalarClamp(Blackhole bh) { + for (int i = 0; i < in.length; i++) { + float v = in[i] * gain + bias; + if (v < 0f) v = 0f; else if (v > 255f) v = 255f; + out[i] = v; + } + bh.consume(out); + } + + @Benchmark + public void vectorClamp(Blackhole bh) { + var vg = FloatVector.broadcast(SP, gain); + var vb = FloatVector.broadcast(SP, bias); + var lo = FloatVector.zero(SP); + var hi = FloatVector.broadcast(SP, 255f); + int i = 0, bound = SP.loopBound(in.length); + for (; i < bound; i += SP.length()) { + FloatVector.fromArray(SP, in, i).fma(vg, vb).max(lo).min(hi).intoArray(out, i); + } + for (; i < in.length; i++) { + float v = in[i] * gain + bias; + if (v < 0f) v = 0f; else if (v > 255f) v = 255f; + out[i] = v; + } + bh.consume(out); + } +}