Skip to content
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

Open
wants to merge 15 commits into
base: master
Choose a base branch
from

Conversation

edeiana
Copy link
Contributor

@edeiana edeiana commented Feb 18, 2025

Scaffolding for the noise generator.
Adds noise_generator_t as a subclass of the iterator reader_t.
Currently noise_generator_t only produces TRACE_TYPE_READ records
with address 0xdeadbeef (easier to spot in tools' output) wrapped in
TRACE_TYPE_THREAD, TRACE_TYPE_PID, and
TRACE_TYPE_THREAD_EXIT.
The noise generator is bundled with the scheduler and is enabled with
-enable_noise_generator (boolean flag). To actually generate synthetic
trace records the user needs to pick how many records to generate with
-noise_generator_num_records (uint64_t flag).

Adds a unit test in scheduler_unit_tests.cpp and an end-to-end test leveraging
the schedule_stats tool.

Issue: #7216

@edeiana edeiana changed the title i#7216 noise generator basic structure i#7216: noise generator basic structure Feb 21, 2025
"with synthetic records.");

droption_t<uint64_t> op_noise_generator_num_records(
DROPTION_SCOPE_FRONTEND, "noise_generator_num_records", 0,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default is 0, but perhaps it should be the number of records of the longest thread of the trace we're adding noise to. Not sure if there is a way to do so at the moment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To your point about the longest thread: I would think most use cases want an infinite stream that doesn't end until all the other inputs have ended. Not sure how to do that...want a callback from the scheduler when it starts thinking about exiting? If we just make this the longest thread instruction count, that thread might have a bunch of wait syscalls and finish along with all the other regular threads and then the scheduler could sit there just running noise (modulo the exit early flag). Need a new scheduler feature to treat as infinite and not count toward exit calculations and just cut off when real inputs indicate exit?

// Add noise generator reader to workload_inputs.
if (options_.enable_noise_generator) {
auto noise_generator = get_noise_generator(options_.noise_generator_num_records);
auto noise_generator_end = get_noise_generator(0);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should have a separate get_noise_generator_end()?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

@edeiana edeiana marked this pull request as ready for review February 21, 2025 11:38
Schedule stats tool results:
Total counts:
4 cores
2 threads: W.*, W.*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really sure why only ci-windows / vs2019-64 does not match this output. The regex seems correct to me. Will investigate.

@@ -157,6 +157,9 @@ Further non-compatibility-affecting changes include:
- Allow v2p.textproto file in a trace directory. This file is present in public traces.
- Allow v2p.textproto file to have one missing virtual_address field, which indicates
virtual_address == 0x0. Necessary in case a trace accesses virtual address 0x0.
- Added noise_generator_t scaffolding as a reader_t to produce synthetic trace records.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the 11.3 list: the next version list is up above.

@@ -157,6 +157,9 @@ Further non-compatibility-affecting changes include:
- Allow v2p.textproto file in a trace directory. This file is present in public traces.
- Allow v2p.textproto file to have one missing virtual_address field, which indicates
virtual_address == 0x0. Necessary in case a trace accesses virtual address 0x0.
- Added noise_generator_t scaffolding as a reader_t to produce synthetic trace records.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to add "in the drmemtrace framework" to give context: remember that this list covers the entire DR release which includes various other tracing sample tools (and calls its internal superblocks "traces").
Ditto below.

@@ -714,6 +714,18 @@ droption_t<std::string>
"Cache hierarchy configuration file",
"The full path to the cache hierarchy configuration file.");

droption_t<bool>
op_enable_noise_generator(DROPTION_SCOPE_FRONTEND, "enable_noise_generator", false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I might want multiple noise streams. These end up looking like software threads and the scheduler will interleave them with real traced threads, right? So to emulate a multi-tenant scenario we might want to add 100 different noise streams, 10 each for 10 different emulated processes and so each with different characteristics? Just trying to plan ahead.

"with synthetic records.");

droption_t<uint64_t> op_noise_generator_num_records(
DROPTION_SCOPE_FRONTEND, "noise_generator_num_records", 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To your point about the longest thread: I would think most use cases want an infinite stream that doesn't end until all the other inputs have ended. Not sure how to do that...want a callback from the scheduler when it starts thinking about exiting? If we just make this the longest thread instruction count, that thread might have a bunch of wait syscalls and finish along with all the other regular threads and then the scheduler could sit there just running noise (modulo the exit early flag). Need a new scheduler feature to treat as infinite and not count toward exit calculations and just cut off when real inputs indicate exit?

return &entry_;
}

// XXX i#7216: this is a temporary trace record that we use as a placeholder until the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be TODO (XXX is too soft: XXX means "nice to have" while this seems required).

// Add noise generator reader to workload_inputs.
if (options_.enable_noise_generator) {
auto noise_generator = get_noise_generator(options_.noise_generator_num_records);
auto noise_generator_end = get_noise_generator(0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

return nullptr;
}

// Do not change the order for generating TRACE_TYPE_THREAD and TRACE_TYPE_PID.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we put this in its own function to share w/ the parent and avoid duplicating here?

if (!marker_tid_generated_) {
entry_ = { TRACE_TYPE_THREAD,
sizeof(int),
{ static_cast<addr_t>(IDLE_THREAD_ID) } };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the idle thread means something special when computing context switch stats: I think this has to have its own unique TID (unique for each instance too). This should not be treated as idle: it should pretend to be a real thread.

if (!marker_pid_generated_) {
entry_ = { TRACE_TYPE_PID,
sizeof(int),
{ static_cast<addr_t>(INVALID_CPU_MARKER_VALUE) } };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should also have a valid but non-colliding value: wouldn't we want to pretend there's another PID here providing these synthetic records?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants