-
Notifications
You must be signed in to change notification settings - Fork 574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
i#7216: noise generator basic structure #7283
base: master
Are you sure you want to change the base?
Conversation
Added -noise_generator_num_records to scheduler options info.
clients/drcachesim/tests/schedule_stats_noise_generator.templatex
Outdated
Show resolved
Hide resolved
that satisfies the scheduler requirements (i.e., noise records must be wrapped between tid, pid, and thread exit). This improved code utilization between noise_generator_t and mock_noise_generator_t in the unit tests.
Using defaults for pid, tid, and num_records. Moved addition of noise_generator_t to workloads in init_scheduler_common().
api/docs/release.dox
Outdated
- Added #dynamorio::drmemtrace::noise_generator_t scaffolding as a | ||
#dynamorio::drmemtrace::reader_t to produce synthetic trace records in the drmemtrace | ||
framework. | ||
- Added #dynamorio::drmemtrace::noise_generator_info_t, which contains the metadata |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make these all a nested list under a top level item on adding noise generator support?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
clients/drcachesim/analyzer.cpp
Outdated
// Add noise generator to workload_inputs. | ||
if (noise_generator_factory_.is_enabled()) { | ||
// TODO i#7216: here can be a good place to analyze the workloads in order to | ||
// tweak noise_generator_info_t parameters. We'd also need a method to replace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Double space
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, thanks!
clients/drcachesim/analyzer.cpp
Outdated
std::string noise_generator_factory_error_string = | ||
noise_generator_factory_.get_error_string(); | ||
if (!noise_generator_factory_error_string.empty()) { | ||
error_string_ = noise_generator_factory_error_string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just assign this instead of using the local var? If we don't want to clobber a pre-existing error: this is already clobbering it; could append.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done (with append).
noise_generator_factory_t<trace_entry_t, record_reader_t>::create_noise_generator( | ||
addr_t pid, addr_t tid, uint64_t num_records) | ||
{ | ||
error_string_ = "Noise generator is not suppported for record_reader_t"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need this to create core-sharded traces via record_filter. Include a TODO or XXX so we know we plan to implement this. Or implement it now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comment. I prefer to break it down, this PR is already on the large side.
get_error_string(); | ||
|
||
void | ||
add_noise_generator_to_workloads( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems an inflexible approach: it doesn't allow adding a noise thread within a an existing process, or a set of noise processes each with different thread counts, or a set of noise threads each with different noise characteristics (load/store mix, etc.). This interface does not seem like it will work for future uses.
I'm going to stick with my original suggestion at https://github.com/DynamoRIO/dynamorio/pull/7283/files#r1973978208 of a factory that takes in a noise_generator_info_t and returns a single input_reader_t. That gives the most flexibility.
Another layer or maybe another method in the same factory could provide convenience support for creating a set of N noise generator threads/processes, but the user can do that through iteration and has full control over the config of each. I guess non-colliding tids/pids is a factor: but this PR doesn't solve that either if the factory is used twice. Maybe the factory for a single one increments an atomic integer to use for the id.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a factory that takes in a noise_generator_info_t and returns a single input_reader_t. That gives the most flexibility.
Agreed. Done.
noise_generator_info_t
now controls a single noise_generator_t
for maximum flexibility.
create_noise_generator()
in noise_generator_factory_t
takes a noise_generator_info_t
and returns a single-process, single-thread noise_generator_t
as an input_reader_t
.
Another layer or maybe another method in the same factory could provide convenience support for creating a set of N noise generator threads/processes, but the user can do that through iteration and has full control over the config of each.
Since we don't have a clear use for that right now, I removed the add_noise_generator_to_workloads()
convenience method. The user is currently responsible for non-colliding PIDs (I think we can have colliding TIDs, as long as they belong to different processes).
init(); | ||
|
||
bool | ||
is_enabled(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This "enabled" seems odd: it's not used to gate the add_ function; it is in fact ignored by the internal code of this class. It doesn't seem like it belongs inside the class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, moved to the analyzer instead.
in the form of an input_reader_t, for max flexibility.
we oonly care about threads anyway.
record in the noise generator.
typename sched_type_t::input_reader_t noise_generator_reader = | ||
noise_generator_factory_.create_noise_generator(noise_generator_info); | ||
// Check for errors. | ||
error_string_ = error_string_ + noise_generator_factory_.get_error_string(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+= should work
if (noise_generator_enabled_) { | ||
// TODO i#7216: here can be a good place to analyze the workloads in order to | ||
// tweak noise_generator_info_t parameters. For now we use noise_generator_info_t | ||
// default values. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also comment that for now we create a single noise thread but we might want more in the future?
op_noise_generator_enable(DROPTION_SCOPE_FRONTEND, "noise_generator_enable", false, | ||
"Enables noise generation.", | ||
"Enables the scheduler to interleave trace records with " | ||
"synthetic records produced by a noise generator."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This description is not clear: it could be interpreted as not actually adding any noise but just enabling someone else to add noise. Make it clear that it adds actual noise inputs. Maybe say right now it adds a single input but that may change in the future, to give us room to auto-add more threads/processes or add other CLI options as we decide in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe even change the name to add_noise_generator
instead of "enable"? That seems clearer.
addr_t pid = 1; | ||
addr_t tid = 1; | ||
uint64_t num_records_to_generate = 1000; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a TODO or XXX about adding parameters controlling the mix of noise: load/store mix, address patterns, etc., so it's clear we don't consider this to be the final set of option fields.
* Contains metadata information to drive the noise generation. | ||
*/ | ||
struct noise_generator_info_t { | ||
noise_generator_info_t() {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use = default;
std::unique_ptr<mock_noise_generator_t>(new mock_noise_generator_t( | ||
noise_generator_info, noise_generator_addr_to_generate)), | ||
std::unique_ptr<mock_noise_generator_t>(new mock_noise_generator_t()), | ||
INVALID_THREAD_ID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this match the info tid? Needs a named constant?
std::vector<scheduler_t::input_workload_t> sched_inputs; | ||
sched_inputs.emplace_back(std::move(readers)); | ||
if (scheduler.init(sched_inputs, 1, | ||
scheduler_t::make_scheduler_serial_options(/*verbosity=*/4)) != |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Serial shouldn't be supported as the max timestamps will put the noise at the very end.
You could do the same as serial but pass DEPENDENCY_IGNORE
(hmm would have to review the scheduler to see what order it would do then).
std::unique_ptr<mock_noise_generator_t>(new mock_noise_generator_t( | ||
noise_generator_info, noise_generator_addr_to_generate)), | ||
std::unique_ptr<mock_noise_generator_t>(new mock_noise_generator_t()), | ||
INVALID_THREAD_ID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a test of using the factory. Seems ok to change this test to use the factory instead?
// There is just one output so we expect to always see 0 as the ordinal. | ||
assert(stream->get_input_workload_ordinal() == 0); | ||
// All TRACE_TYPE_READ records are generated by the noise generator and their | ||
// addr is always the constant noise_generator_addr_to_generate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to do this arrangement with the only reads in the noise: you have the tid of the noise input, and you also have the ordinal of the noise input. You can use one of those, and then put reads in the other inputs, which seems a stronger check.
Schedule stats tool results: | ||
Total counts: | ||
*[1-9][0-9]* cores | ||
2 threads:.* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The small_trace_file IIRC is asm with a fixed known count of record types, and other tests rely on those? So should we check that the result has small_trace_file read count plus 100? Is 100 hidden from us?
Scaffolding for the noise generator.
Adds
noise_generator_t
as a subclass of the iteratorreader_t
.Currently
noise_generator_t
only producesTRACE_TYPE_READ
recordswith address
0xdeadbeef
(easier to spot in tools' output). These records arepreceded by
TRACE_TYPE_THREAD
,TRACE_TYPE_PID
,TRACE_MARKER_TYPE_TIMESTAMP
and followed byTRACE_TYPE_THREAD_EXIT
as this is the sequence of records the scheduler expects.
As of now, the user can add a single-process, single-thread noise generator workload to
the scheduler's input workloads through the
-noise_generator_enable
analyzer optionin the drmemtrace framework. Adding a
noise_generator_t
to the scheduler's inputworkloads is done by the factory class
noise_generator_factory_t
through itscreate_noise_generator()
method, which returns a noise generator as aninput_reader_t
that can then be added to the scheduler'sinput_workload_t
vector. Currently, there are three knobs the user can control in the noise generator:
PID, TID, and number of noise records to generate. These knobs are encapsulated
in the
noise_generator_info_t
struct. For now they are pre-set with default values:PID = 1, TID = 1, number of noise records to generate = 1000.
Adds a unit test in scheduler_unit_tests.cpp and an end-to-end test leveraging
the
schedule_stats
tool.Issue: #7216