Skip to content

Commit

Permalink
Review requests: rename to exit_if_fraction_inputs_left; make sched d…
Browse files Browse the repository at this point in the history
…efault match CLI; print inputs left; augment comments; improve atomic assert
  • Loading branch information
derekbruening committed Oct 3, 2024
1 parent c7eb1af commit 45c7afe
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 25 deletions.
3 changes: 2 additions & 1 deletion clients/drcachesim/analyzer_multi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,8 @@ analyzer_multi_tmpl_t<RecordType, ReaderType>::init_dynamic_schedule()
sched_ops.rebalance_period_us = op_sched_rebalance_period_us.get_value();
sched_ops.randomize_next_input = op_sched_randomize.get_value();
sched_ops.honor_direct_switches = !op_sched_disable_direct_switches.get_value();
sched_ops.exit_if_fraction_left = op_sched_exit_if_fraction_left.get_value();
sched_ops.exit_if_fraction_inputs_left =
op_sched_exit_if_fraction_inputs_left.get_value();
#ifdef HAS_ZIP
if (!op_record_file.get_value().empty()) {
record_schedule_zip_.reset(new zipfile_ostream_t(op_record_file.get_value()));
Expand Down
11 changes: 5 additions & 6 deletions clients/drcachesim/common/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1034,18 +1034,17 @@ droption_t<uint64_t> op_sched_rebalance_period_us(
"The period in simulated microseconds at which per-core run queues are re-balanced "
"to redistribute load.");

droption_t<double> op_sched_exit_if_fraction_left(
// Our default value here targets core-sharded analyzers where we want to avoid idle
// tails: that's why we have a 5%-exit-early default here, vs the scheduler's own
// option's default of 0 which lets a simulator choose when to exit.
DROPTION_SCOPE_FRONTEND, "sched_exit_if_fraction_left", 0.05,
droption_t<double> op_sched_exit_if_fraction_inputs_left(
DROPTION_SCOPE_FRONTEND, "sched_exit_if_fraction_inputs_left", 0.05,
"Exit if non-EOF inputs left are <= this fraction of the total",
"Applies to -core_sharded and -core_serial. When an input reaches EOF, if the "
"number of non-EOF inputs left as a fraction of the original inputs is equal to or "
"less than this value then the scheduler exits (sets all outputs to EOF) rather than "
"finishing off the final inputs. This helps avoid long sequences of idles during "
"staggered endings with fewer inputs left than cores and only a small fraction of "
"the total instructions left in those inputs.");
"the total instructions left in those inputs. Since the remaining instruction "
"count is not considered (as it is not available), use discretion when raising "
"this value on uneven inputs.");

// Schedule_stats options.
droption_t<uint64_t>
Expand Down
2 changes: 1 addition & 1 deletion clients/drcachesim/common/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ extern dynamorio::droption::droption_t<bool> op_sched_infinite_timeouts;
extern dynamorio::droption::droption_t<uint64_t> op_sched_migration_threshold_us;
extern dynamorio::droption::droption_t<uint64_t> op_sched_rebalance_period_us;
extern dynamorio::droption::droption_t<double> op_sched_time_units_per_us;
extern dynamorio::droption::droption_t<double> op_sched_exit_if_fraction_left;
extern dynamorio::droption::droption_t<double> op_sched_exit_if_fraction_inputs_left;
extern dynamorio::droption::droption_t<uint64_t> op_schedule_stats_print_every;
extern dynamorio::droption::droption_t<std::string> op_syscall_template_file;
extern dynamorio::droption::droption_t<uint64_t> op_filter_stop_timestamp;
Expand Down
23 changes: 13 additions & 10 deletions clients/drcachesim/scheduler/scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,8 +725,8 @@ scheduler_tmpl_t<RecordType, ReaderType>::print_configuration()
options_.rebalance_period_us);
VPRINT(this, 1, " %-25s : %d\n", "honor_infinite_timeouts",
options_.honor_infinite_timeouts);
VPRINT(this, 1, " %-25s : %f\n", "exit_if_fraction_left",
options_.exit_if_fraction_left);
VPRINT(this, 1, " %-25s : %f\n", "exit_if_fraction_inputs_left",
options_.exit_if_fraction_inputs_left);
}

template <typename RecordType, typename ReaderType>
Expand Down Expand Up @@ -1029,8 +1029,9 @@ scheduler_tmpl_t<RecordType, ReaderType>::legacy_field_support()
error_string_ = "block_time_max_us must be > 0";
return STATUS_ERROR_INVALID_PARAMETER;
}
if (options_.exit_if_fraction_left < 0. || options_.exit_if_fraction_left > 1.) {
error_string_ = "exit_if_fraction_left must be 0..1";
if (options_.exit_if_fraction_inputs_left < 0. ||
options_.exit_if_fraction_inputs_left > 1.) {
error_string_ = "exit_if_fraction_inputs_left must be 0..1";
return STATUS_ERROR_INVALID_PARAMETER;
}
return STATUS_SUCCESS;
Expand Down Expand Up @@ -4194,14 +4195,15 @@ scheduler_tmpl_t<RecordType, ReaderType>::mark_input_eof(input_info_t &input)
if (input.at_eof)
return sched_type_t::STATUS_OK;
input.at_eof = true;
assert(live_input_count_.load(std::memory_order_acquire) > 0);
live_input_count_.fetch_add(-1, std::memory_order_release);
int old_count = live_input_count_.fetch_add(-1, std::memory_order_release);
assert(old_count > 0);
int live_inputs = live_input_count_.load(std::memory_order_acquire);
VPRINT(this, 2, "input %d at eof; %d live inputs left\n", input.index, live_inputs);
if (options_.mapping == MAP_TO_ANY_OUTPUT &&
live_inputs <=
static_cast<int>(inputs_.size() * options_.exit_if_fraction_left)) {
VPRINT(this, 1, "exiting early at input %d\n", input.index);
static_cast<int>(inputs_.size() * options_.exit_if_fraction_inputs_left)) {
VPRINT(this, 1, "exiting early at input %d with %d live inputs left\n",
input.index, live_inputs);
return sched_type_t::STATUS_EOF;
}
return sched_type_t::STATUS_OK;
Expand All @@ -4227,8 +4229,9 @@ scheduler_tmpl_t<RecordType, ReaderType>::eof_or_idle(output_ordinal_t output,
}
if (options_.mapping == MAP_TO_ANY_OUTPUT &&
live_inputs <=
static_cast<int>(inputs_.size() * options_.exit_if_fraction_left)) {
VPRINT(this, 1, "output %d exiting early\n", output);
static_cast<int>(inputs_.size() * options_.exit_if_fraction_inputs_left)) {
VPRINT(this, 1, "output %d exiting early with %d live inputs left\n", output,
live_inputs);
return sched_type_t::STATUS_EOF;
}
// Before going idle, try to steal work from another output.
Expand Down
9 changes: 7 additions & 2 deletions clients/drcachesim/scheduler/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -811,9 +811,11 @@ template <typename RecordType, typename ReaderType> class scheduler_tmpl_t {
* this value then the scheduler exits (sets all outputs to EOF) rather than
* finishing off the final inputs. This helps avoid long sequences of idles
* during staggered endings with fewer inputs left than cores and only a small
* fraction of the total instructions left in those inputs.
* fraction of the total instructions left in those inputs. Since the remaining
* instruction count is not considered (as it is not available), use discretion
* when raising this value on uneven inputs.
*/
double exit_if_fraction_left = 0.1;
double exit_if_fraction_inputs_left = 0.05;
// When adding new options, also add to print_configuration().
};

Expand Down Expand Up @@ -2030,6 +2032,9 @@ template <typename RecordType, typename ReaderType> class scheduler_tmpl_t {
set_output_active(output_ordinal_t output, bool active);

// Caller must hold the input's lock.
// The return value is STATUS_EOF if a global exit is now happening (an
// early exit); otherwise STATUS_OK is returned on success but only a
// local EOF.
stream_status_t
mark_input_eof(input_info_t &input);

Expand Down
10 changes: 5 additions & 5 deletions clients/drcachesim/tests/scheduler_unit_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1599,7 +1599,7 @@ test_synthetic_with_timestamps()
/*verbosity=*/3);
sched_ops.quantum_duration_instrs = 3;
// Test dropping a final "_" from core0.
sched_ops.exit_if_fraction_left = 0.1;
sched_ops.exit_if_fraction_inputs_left = 0.1;
scheduler_t scheduler;
if (scheduler.init(sched_inputs, NUM_OUTPUTS, std::move(sched_ops)) !=
scheduler_t::STATUS_SUCCESS)
Expand Down Expand Up @@ -1701,7 +1701,7 @@ test_synthetic_with_priorities()
/*verbosity=*/3);
sched_ops.quantum_duration_instrs = 3;
// Test dropping a final "_" from core0.
sched_ops.exit_if_fraction_left = 0.1;
sched_ops.exit_if_fraction_inputs_left = 0.1;
scheduler_t scheduler;
if (scheduler.init(sched_inputs, NUM_OUTPUTS, std::move(sched_ops)) !=
scheduler_t::STATUS_SUCCESS)
Expand Down Expand Up @@ -2035,7 +2035,7 @@ test_synthetic_with_syscalls_multiple()
sched_ops.blocking_switch_threshold = BLOCK_LATENCY;
sched_ops.block_time_multiplier = BLOCK_SCALE;
// Test dropping a bunch of final "_" from core1.
sched_ops.exit_if_fraction_left = 0.1;
sched_ops.exit_if_fraction_inputs_left = 0.1;
scheduler_t scheduler;
if (scheduler.init(sched_inputs, NUM_OUTPUTS, std::move(sched_ops)) !=
scheduler_t::STATUS_SUCCESS)
Expand Down Expand Up @@ -6053,7 +6053,7 @@ test_exit_early()
sched_ops.time_units_per_us = 1.;
sched_ops.quantum_duration_instrs = QUANTUM_DURATION;
sched_ops.blocking_switch_threshold = BLOCK_LATENCY;
sched_ops.exit_if_fraction_left = 0.;
sched_ops.exit_if_fraction_inputs_left = 0.;
scheduler_t scheduler;
if (scheduler.init(sched_inputs, NUM_OUTPUTS, std::move(sched_ops)) !=
scheduler_t::STATUS_SUCCESS)
Expand Down Expand Up @@ -6092,7 +6092,7 @@ test_exit_early()
sched_ops.quantum_duration_instrs = QUANTUM_DURATION;
sched_ops.blocking_switch_threshold = BLOCK_LATENCY;
// NUM_INPUTS=11 * 0.1 = 1.1 so we'll exit with 1 input left.
sched_ops.exit_if_fraction_left = 0.1;
sched_ops.exit_if_fraction_inputs_left = 0.1;
scheduler_t scheduler;
if (scheduler.init(sched_inputs, NUM_OUTPUTS, std::move(sched_ops)) !=
scheduler_t::STATUS_SUCCESS)
Expand Down

0 comments on commit 45c7afe

Please sign in to comment.