diff --git a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/capture/FrameSampleSet.java b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/capture/FrameSampleSet.java index f5948a311..91ccdc9fe 100644 --- a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/capture/FrameSampleSet.java +++ b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/capture/FrameSampleSet.java @@ -37,6 +37,9 @@ public class FrameSampleSet extends ArrayList { double product = 1.0; for (FrameSample sample : this) { double weighted = sample.weightedValue(); + if (Double.isNaN(weighted)||Double.isInfinite(weighted)) { + throw new RuntimeException("Not a real value for '" + sample.criterion().name() + "': " + weighted); + } product *= weighted; } return product; diff --git a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimo/SC_optimo.java b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimo/SC_optimo.java index d9ed06eeb..859ba866a 100644 --- a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimo/SC_optimo.java +++ b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimo/SC_optimo.java @@ -32,6 +32,7 @@ import io.nosqlbench.scenarios.simframe.capture.SimFrameCapture; import io.nosqlbench.scenarios.simframe.capture.SimFrameJournal; import io.nosqlbench.scenarios.simframe.findmax.SC_findmax; import io.nosqlbench.scenarios.simframe.planning.SimFrameFunction; +import io.nosqlbench.scenarios.simframe.stabilization.StatFunctions; import org.apache.commons.math4.legacy.exception.MathIllegalStateException; import org.apache.commons.math4.legacy.optim.*; import org.apache.commons.math4.legacy.optim.nonlinear.scalar.GoalType; @@ -177,6 +178,8 @@ public class SC_optimo extends SCBaseScenario { SimFrameCapture sampler = new SimFrameCapture(); NBMetricTimer result_timer = activity.find().timer("name:result"); + NBMetricTimer latency_histo = result_timer.attachHdrDeltaHistogram(); + NBMetricTimer result_success_timer = activity.find().timer("name:result_success"); NBMetricGauge cyclerate_gauge = activity.find().gauge("name=config_cyclerate"); NBMetricHistogram tries_histo_src = activity.find().histogram("name=tries"); @@ -200,8 +203,12 @@ public class SC_optimo extends SCBaseScenario { double triesP99 = tries_histo.getDeltaSnapshot(90).get99thPercentile(); return 1/triesP99; }); - - + sampler.addDirect("latency_cutoff_50", () -> { + double latencyP99 = latency_histo.getDeltaSnapshot(90).getP99ms(); + double v = StatFunctions.sigmoidE4LowPass(latencyP99, 50); +// System.out.println("v:"+v+" p99ms:" + latencyP99); + return v; + },1.0d); return sampler; } } diff --git a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/stabilization/StabilityDetector.java b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/stabilization/StabilityDetector.java index 22db9ee33..6d80b3c7e 100644 --- a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/stabilization/StabilityDetector.java +++ b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/stabilization/StabilityDetector.java @@ -108,12 +108,12 @@ public class StabilityDetector implements Runnable { basis *= reductionFactor; } - double time = ((double)(nextCheckAt - startedAt))/1000d; - System.out.printf("% 4.1fS STABILITY %g :", time, basis); - for (int i = 0; i < stddev.length; i++) { - System.out.printf("[%d]: %g ", windows[i], stddev[i]); - } - System.out.println(); +// double time = ((double)(nextCheckAt - startedAt))/1000d; +// System.out.printf("% 4.1fS STABILITY %g :", time, basis); +// for (int i = 0; i < stddev.length; i++) { +// System.out.printf("[%d]: %g ", windows[i], stddev[i]); +// } +// System.out.println(); return basis; } diff --git a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/stabilization/StatFunctions.java b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/stabilization/StatFunctions.java index 9946138ad..346d92cdc 100644 --- a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/stabilization/StatFunctions.java +++ b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/stabilization/StatFunctions.java @@ -21,36 +21,27 @@ import java.util.ListIterator; import java.util.function.ToDoubleFunction; public class StatFunctions { -// public static double[] lastStddev(int[] ranges, LinkedList values) { -// double[] avgs = new double[ranges.length]; -// for (int i = 0; i < ranges.length; i++) { -// int range = ranges[i]; -// if (values.size()>=range) { -// double avg=0.0d; -// ListIterator iter = listIterator(size() - range); -// while (iter.hasNext()) avg += (iter.next().value / range); -// avgs[i]=avg; -// } else { -// avgs[i]=Double.NaN; -// } -// } -// -// } -// -// public static double[] stackedSample(LinkedList values, ToDoubleFunction func, int... windows) { -// double[] results = new double[windows.length]; -// for (int i = 0; i < windows.length; i++) { -// int range = windows[i]; -// if (values.size()>=range) { -// double avg=0.0d; -// ListIterator iter = listIterator(size() - range); -// while (iter.hasNext()) avg += (iter.next().value / range); -// results[i]=avg; -// } else { -// results[i]=Double.NaN; -// } -// } -// -// -// } + /** + * A continuous sigmoid function which looks very close to a step function at the inflection points. + * This provides a navigable surface for optimizers while also acting like an all-or none filter. + * This function yields 0.0d or 1.0d over most of its domain, except between shelf-0.0025 and shelf, + * where it is a steep sigmoid. Specifically, at shelf, the value is 1.0; at shelf-0.0001, the value is 0.9999, + * dropping quickly on the lower side of shelf, leveling out at 0.0 at shelf-0.0025. + * @param input x + * @param lowcut The point on the x axis at which all higher values should yield 1.0 + */ + public static double sigmoidE4HighPass(double input, double lowcut) { + return 1.0d/(1.0d+Math.pow(Math.E,(-10000.0d*(input-(lowcut-0.001d))))); + } + /** + * Like {@link #sigmoidE4HighPass, but inverted with respect to the Y axis. This has the same roll-off charater + * where the high (1.0) shelf in included through the cutoff value. + * @param input x + * @param lowcut The point on the x axis at which all lower values should yield 1.0 + */ + public static double sigmoidE4LowPass(double input, double highcut) { + double v = 1.0d/(1.0d + Math.pow(Math.E, (10000.0d * (input - (highcut + 0.001d))))); + return v; + } + }