Skip to content

Commit 7e692b0

Browse files
i#7091: Add -multi_indir to drmemtrace (#7242)
Adds a new option -multi_indir to the drmemtrace framework. This allows combining multiple workload traces in core-sharded mode, interleaving threads from all the workloads together. Updates the documentation. Adds a test that runs 3 copies of the checked-in threadsig trace. Manually tested error checking: ``` $ bin64/drrun -t drmemtrace -tool schedule_stats -cores 3 -multi_indir ../src/clients/drcachesim/tests/drmemtrace.threadsig.x64.tracedir:../src/clients/drcachesim/tests/drmemtrace.threadsig.x64.tracedir:../src/clients/drcachesim/tests/drmemtrace.threadsig.x64.tracedir -only_shards 1 ERROR: failed to initialize analyzer: Input limits are not currently supported with -multi_indir ``` Issue: #7091
1 parent ac47745 commit 7e692b0

File tree

10 files changed

+212
-107
lines changed

10 files changed

+212
-107
lines changed

clients/drcachesim/analyzer.cpp

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* **********************************************************
2-
* Copyright (c) 2016-2024 Google, Inc. All rights reserved.
2+
* Copyright (c) 2016-2025 Google, Inc. All rights reserved.
33
* **********************************************************/
44

55
/*
@@ -229,13 +229,13 @@ analyzer_tmpl_t<RecordType, ReaderType>::analyzer_tmpl_t()
229229
template <typename RecordType, typename ReaderType>
230230
bool
231231
analyzer_tmpl_t<RecordType, ReaderType>::init_scheduler(
232-
const std::string &trace_path, const std::set<memref_tid_t> &only_threads,
233-
const std::set<int> &only_shards, int output_limit, int verbosity,
234-
typename sched_type_t::scheduler_options_t options)
232+
const std::vector<std::string> &trace_paths,
233+
const std::set<memref_tid_t> &only_threads, const std::set<int> &only_shards,
234+
int output_limit, int verbosity, typename sched_type_t::scheduler_options_t options)
235235
{
236236
verbosity_ = verbosity;
237-
if (trace_path.empty()) {
238-
ERRMSG("Trace file name is empty\n");
237+
if (trace_paths.empty()) {
238+
ERRMSG("Missing trace path(s)\n");
239239
return false;
240240
}
241241
std::vector<typename sched_type_t::range_t> regions;
@@ -246,14 +246,24 @@ analyzer_tmpl_t<RecordType, ReaderType>::init_scheduler(
246246
// capability in the scheduler we should switch to that.
247247
regions.emplace_back(skip_instrs_ + 1, 0);
248248
}
249-
typename sched_type_t::input_workload_t workload(trace_path, regions);
250-
workload.only_threads = only_threads;
251-
workload.only_shards = only_shards;
252-
workload.output_limit = output_limit;
253-
if (regions.empty() && skip_to_timestamp_ > 0) {
254-
workload.times_of_interest.emplace_back(skip_to_timestamp_, 0);
249+
std::vector<typename sched_type_t::input_workload_t> workloads;
250+
for (const std::string &path : trace_paths) {
251+
if (path.empty()) {
252+
ERRMSG("Trace path is empty\n");
253+
return false;
254+
}
255+
workloads.emplace_back(path, regions);
256+
// As documented and checked in analyzer_multi.cpp, only_threads and only_shards
257+
// limits are not supported with -multi_indir. That's already been checked, so
258+
// we do not perform additional checks here.
259+
workloads.back().only_threads = only_threads;
260+
workloads.back().only_shards = only_shards;
261+
workloads.back().output_limit = output_limit;
262+
if (regions.empty() && skip_to_timestamp_ > 0) {
263+
workloads.back().times_of_interest.emplace_back(skip_to_timestamp_, 0);
264+
}
255265
}
256-
return init_scheduler_common(workload, std::move(options));
266+
return init_scheduler_common(workloads, std::move(options));
257267
}
258268

259269
template <typename RecordType, typename ReaderType>
@@ -274,14 +284,15 @@ analyzer_tmpl_t<RecordType, ReaderType>::init_scheduler(
274284
std::vector<typename sched_type_t::range_t> regions;
275285
if (skip_instrs_ > 0)
276286
regions.emplace_back(skip_instrs_ + 1, 0);
277-
typename sched_type_t::input_workload_t workload(std::move(readers), regions);
278-
return init_scheduler_common(workload, std::move(options));
287+
std::vector<typename sched_type_t::input_workload_t> workloads;
288+
workloads.emplace_back(std::move(readers), regions);
289+
return init_scheduler_common(workloads, std::move(options));
279290
}
280291

281292
template <typename RecordType, typename ReaderType>
282293
bool
283294
analyzer_tmpl_t<RecordType, ReaderType>::init_scheduler_common(
284-
typename sched_type_t::input_workload_t &workload,
295+
std::vector<typename sched_type_t::input_workload_t> &workloads,
285296
typename sched_type_t::scheduler_options_t options)
286297
{
287298
for (int i = 0; i < num_tools_; ++i) {
@@ -290,8 +301,6 @@ analyzer_tmpl_t<RecordType, ReaderType>::init_scheduler_common(
290301
break;
291302
}
292303
}
293-
std::vector<typename sched_type_t::input_workload_t> sched_inputs(1);
294-
sched_inputs[0] = std::move(workload);
295304

296305
typename sched_type_t::scheduler_options_t sched_ops;
297306
int output_count = worker_count_;
@@ -326,7 +335,7 @@ analyzer_tmpl_t<RecordType, ReaderType>::init_scheduler_common(
326335
output_count = 1;
327336
}
328337
sched_mapping_ = options.mapping;
329-
if (scheduler_.init(sched_inputs, output_count, std::move(sched_ops)) !=
338+
if (scheduler_.init(workloads, output_count, std::move(sched_ops)) !=
330339
sched_type_t::STATUS_SUCCESS) {
331340
ERRMSG("Failed to initialize scheduler: %s\n",
332341
scheduler_.get_error_string().c_str());
@@ -384,7 +393,7 @@ analyzer_tmpl_t<RecordType, ReaderType>::analyzer_tmpl_t(
384393
// The scheduler will call reader_t::init() for each input file. We assume
385394
// that won't block (analyzer_multi_t separates out IPC readers).
386395
typename sched_type_t::scheduler_options_t sched_ops;
387-
if (!init_scheduler(trace_path, {}, {}, /*output_limit=*/0, verbosity,
396+
if (!init_scheduler({ trace_path }, {}, {}, /*output_limit=*/0, verbosity,
388397
std::move(sched_ops))) {
389398
success_ = false;
390399
error_string_ = "Failed to create scheduler";

clients/drcachesim/analyzer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* **********************************************************
2-
* Copyright (c) 2016-2024 Google, Inc. All rights reserved.
2+
* Copyright (c) 2016-2025 Google, Inc. All rights reserved.
33
* **********************************************************/
44

55
/*
@@ -218,7 +218,7 @@ template <typename RecordType, typename ReaderType> class analyzer_tmpl_t {
218218
};
219219

220220
bool
221-
init_scheduler(const std::string &trace_path,
221+
init_scheduler(const std::vector<std::string> &trace_paths,
222222
// To include all threads/shards, use empty sets.
223223
const std::set<memref_tid_t> &only_threads,
224224
const std::set<int> &only_shards, int output_limit, int verbosity,
@@ -234,7 +234,7 @@ template <typename RecordType, typename ReaderType> class analyzer_tmpl_t {
234234
typename sched_type_t::scheduler_options_t options);
235235

236236
bool
237-
init_scheduler_common(typename sched_type_t::input_workload_t &workload,
237+
init_scheduler_common(std::vector<typename sched_type_t::input_workload_t> &workloads,
238238
typename sched_type_t::scheduler_options_t options);
239239

240240
// Used for std::thread so we need an rvalue (so no &worker).

0 commit comments

Comments
 (0)