Merge pull request #1931 from nosqlbench/mwolters/optimize

Mwolters/optimize
This commit is contained in:
Jonathan Shook 2024-04-17 22:47:55 -05:00 committed by GitHub
commit dead305986
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 85 additions and 27 deletions

View File

@ -57,7 +57,7 @@ public class CMD_findmax extends NBBaseCommand {
FindmaxConfig findmaxConfig = new FindmaxConfig(params);
switch(findmaxConfig.optimization_type()) {
case "rate" ->
case "rate" -> {
model.add("rate",
findmaxConfig.min_value(), // min
findmaxConfig.base_value(), // initial
@ -67,13 +67,24 @@ public class CMD_findmax extends NBBaseCommand {
1.1d,
SimRateSpec.Verb.restart)))
);
case "threads" ->
if (findmaxConfig.contra_base_value() != 0) {
flywheel.onEvent(ParamChange.of(new SetThreads((int) (findmaxConfig.contra_base_value()))));
}
}
case "threads" -> {
model.add("threads",
findmaxConfig.min_value(), // min
findmaxConfig.base_value(), // initial
findmaxConfig.max_value(), // max
threads -> flywheel.onEvent(ParamChange.of(new SetThreads((int) (threads))))
);
if (findmaxConfig.contra_base_value() != 0) {
flywheel.onEvent(ParamChange.of(new CycleRateSpec(
findmaxConfig.contra_base_value(),
1.1d,
SimRateSpec.Verb.restart)));
}
}
default ->
throw new RuntimeException("Unsupported optimization type: " + findmaxConfig.optimization_type());
}

View File

@ -31,6 +31,12 @@ public class FindmaxAnalyzer extends SimFrameFunctionAnalyzer<FindmaxFrameFuncti
super(function, config);
}
protected boolean shouldStop(SimFrame<FindmaxFrameParams> compFrame) {
return function.getJournal().frames().size() >= config.min_frames() &&
((compFrame.params().paramValues()[0] + config.step_value()) -
(function.getJournal().bestRun().params().paramValues()[0] + config.step_value())) <= config.step_value();
}
@Override
protected FrameResult nextFrame() {
double newValue;
@ -42,54 +48,36 @@ public class FindmaxAnalyzer extends SimFrameFunctionAnalyzer<FindmaxFrameFuncti
config.sample_time_ms(),
config.max_value(),
config.base_value(),
config.contra_base_value(),
config.min_value(),
(config.step_value() * config.value_incr()),
config.value_incr(),
config.sample_incr(),
config.min_settling_ms(),
config.min_frames(),
config.optimization_type(),
new double[]{newValue}
);
} else if (best.index() == last.index() - 1) {
// got worse consecutively, this may be collapsed out since the general case below covers it (test first)
if (((last.params().paramValues()[0] + config.step_value()) -
(best.params().paramValues()[0] + config.step_value())) <= config.step_value()) {
logger.info("could not divide search space further, stop condition met");
return new FrameResult(best.params().paramValues()[0], SimFrameAction.stop_run);
} else {
newValue = best.params().paramValues()[0] + config.step_value();
config = new FindmaxConfig(
(config.sample_time_ms() * config.sample_incr()),
config.max_value(),
config.base_value(),
config.min_value(),
config.step_value(),
config.value_incr(),
config.sample_incr(),
(config.min_settling_ms() * 4),
config.optimization_type(),
new double[]{newValue}
);
}
} else { // any other case
} else {
// find next frame with higher rate but lower value, the closest one by rate
SimFrame<FindmaxFrameParams> nextWorseFrameWithHigherRate = function.getJournal().frames().stream()
.filter(f -> f.value() < best.value())
.filter(f -> f.params().paramValues()[0] + config.step_value() > (best.params().paramValues()[0] + config.step_value()))
.min(Comparator.comparingDouble(f -> f.params().paramValues()[0] + config.step_value()))
.orElseThrow(() -> new RuntimeException("inconsistent samples"));
if ((nextWorseFrameWithHigherRate.params().paramValues()[0] + config.step_value() -
best.params().paramValues()[0] + config.step_value()) > config.step_value()) {
if (!shouldStop(nextWorseFrameWithHigherRate)) {
newValue = best.params().paramValues()[0] + config.step_value();
config = new FindmaxConfig(
(config.sample_time_ms() * config.sample_incr()),
config.max_value(),
config.base_value(),
config.contra_base_value(),
config.min_value(),
config.step_value(),
config.value_incr(),
config.sample_incr(),
(config.min_settling_ms() * 2),
config.min_frames(),
config.optimization_type(),
new double[]{newValue}
);

View File

@ -22,11 +22,13 @@ public record FindmaxConfig (
double sample_time_ms,
double max_value,
double base_value,
double contra_base_value,
double min_value,
double step_value,
double value_incr,
double sample_incr,
long min_settling_ms,
long min_frames,
String optimization_type,
double[] initial_point
) {
@ -39,11 +41,13 @@ public record FindmaxConfig (
params.maybeGet("sample_time_ms").map(Double::parseDouble).orElse(4000d),
params.maybeGet("max_value").map(Double::parseDouble).orElse(10000d),
params.maybeGet("base_value").map(Double::parseDouble).orElse(10d),
params.maybeGet("contra_base_value").map(Double::parseDouble).orElse(0d),
params.maybeGet("min_value").map(Double::parseDouble).orElse(0d),
params.maybeGet("step_value").map(Double::parseDouble).orElse(100d),
params.maybeGet("value_incr").map(Double::parseDouble).orElse(2d),
params.maybeGet("sample_incr").map(Double::parseDouble).orElse(1.2d),
params.maybeGet("min_settling_ms").map(Long::parseLong).orElse(4000L),
params.maybeGet("min_frames").map(Long::parseLong).orElse(5L),
params.maybeGet("optimization_type").orElse("rate"),
new double[]{params.maybeGet("base_value").map(Double::parseDouble).orElse(10d)}
);

View File

@ -86,7 +86,7 @@ public class CMD_optimo extends NBBaseCommand {
model.add("rate", 10, optimoSearchParams.startRate(), optimoSearchParams.startRate()*4,
rate -> flywheel.onEvent(ParamChange.of(new CycleRateSpec(rate, 1.1d, SimRateSpec.Verb.restart)))
);
model.add("threads", 10, 50, 2000,
model.add("threads", 10, optimoSearchParams.start_threads(), 2000,
threads -> flywheel.onEvent(ParamChange.of(new SetThreads((int) (threads))))
);

View File

@ -24,6 +24,7 @@ public record OptimoSearchSettings(
long sample_time_ms,
double cutoff_quantile,
double cutoff_ms,
double start_threads,
OptimoParamModel model
) {
public OptimoSearchSettings(NBCommandParams params, OptimoParamModel model) {
@ -32,6 +33,7 @@ public record OptimoSearchSettings(
params.maybeGet("sample_time_ms").map(Long::parseLong).orElse(5000L),
params.maybeGet("cutoff_quantile").map(Double::parseDouble).orElse(0.99),
params.maybeGet("cutoff_ms").map(Double::parseDouble).orElse(50.0d),
params.maybeGet("start_threads").map(Double::parseDouble).orElse(50.0d),
model
);
}

View File

@ -0,0 +1,14 @@
scenarios:
optimize_rate:
query: start alias=query_step tags='block:query' driver=stdout cycles=1000
findmax: findmax activity=query_step base_value=100 step_value=50 min_frames=5 optimization_type=rate
optimo: optimo activity=query_step startrate=${findmax.rate}
bindings:
number: Identity()
blocks:
query:
ops:
query_op: "SELECT * FROM my_table WHERE id={number};"

View File

@ -0,0 +1,14 @@
scenarios:
optimize_rate:
query: start alias=query_step tags='block:query' driver=stdout cycles=1000
findmax: findmax activity=query_step base_value=20 step_value=10 min_frames=5 optimization_type=threads
optimo: optimo activity=query_step start_threads=${findmax.threads}
bindings:
number: Identity()
blocks:
query:
ops:
query_op: "SELECT * FROM my_table WHERE id={number};"

View File

@ -0,0 +1,13 @@
scenarios:
optimize_rate:
query: start alias=query_step tags='block:query' driver=stdout cycles=1000
findmax: findmax activity=query_step base_value=100 step_value=50 min_frames=5 optimization_type=rate
bindings:
number: Identity()
blocks:
query:
ops:
query_op: "SELECT * FROM my_table WHERE id={number};"

View File

@ -0,0 +1,12 @@
scenarios:
optimize_rate:
query: start alias=query_step tags='block:query' driver=stdout cycles=1000
findmax: findmax activity=query_step base_value=20 step_value=10 min_frames=5 optimization_type=threads
bindings:
number: Identity()
blocks:
query:
ops:
query_op: "SELECT * FROM my_table WHERE id={number};"