Skip to content

Commit

Permalink
i#4857: Add instr count to drmemtrace filtered traces (#4864)
Browse files Browse the repository at this point in the history
Adds tracking of the dynamic (pre-filtered) instruction count for each thread.
Stores the count in a marker at thread exit (storing prior to each miss entry
might be useful but in experiments it adds too much overhead to include
without a clear mandate and possibly under an off-by-default runtime option).

Adds a check to the filter tests confirming that the instruction count
marker is present at thread exit for filtered traces.  This is done by
invoked test_mode for these traces.  To simplify testing for online
and offline, the trace type marker is added to online traces.

Adds a new tool.drcachesim.filter-asm test which ensures the instr
count is the precise count expected for that fully-deterministic
tiny static binary.

A larger-than-static-asm application was manually tested, confirming
the need for the rep string expansion special case in the code to
limit to 1 instruction for that block.

Fixes #4857
  • Loading branch information
derekbruening authored Apr 21, 2021
1 parent 221d581 commit c530f52
Show file tree
Hide file tree
Showing 15 changed files with 205 additions and 49 deletions.
6 changes: 3 additions & 3 deletions clients/drcachesim/analyzer_multi.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2016-2020 Google, Inc. All rights reserved.
* Copyright (c) 2016-2021 Google, Inc. All rights reserved.
* **********************************************************/

/*
Expand Down Expand Up @@ -174,8 +174,8 @@ analyzer_multi_t::create_analysis_tools()
num_tools_ = 1;
#ifdef DEBUG
if (op_test_mode.get_value()) {
tools_[1] =
new trace_invariants_t(op_offline.get_value(), op_verbose.get_value());
tools_[1] = new trace_invariants_t(op_offline.get_value(), op_verbose.get_value(),
op_test_mode_name.get_value());
if (tools_[1] == NULL)
return false;
if (!!*tools_[1])
Expand Down
15 changes: 9 additions & 6 deletions clients/drcachesim/common/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,13 @@ droption_t<std::string> op_LL_miss_file(

droption_t<bool> op_L0_filter(
DROPTION_SCOPE_CLIENT, "L0_filter", false,
"Filter out zero-level hits during tracing",
"Filter out first-level cache hits during tracing",
"Filters out instruction and data hits in a 'zero-level' cache during tracing "
"itself, "
"shrinking the final trace to only contain instruction and data accesses that miss "
"in "
"this initial cache. This cache is direct-mapped with sizes equal to -L0I_size and "
"-L0D_size. It uses virtual addresses regardless of -use_physical.");
"itself, shrinking the final trace to only contain instruction and data accesses "
"that miss in this initial cache. This cache is direct-mapped with sizes equal to "
"-L0I_size and -L0D_size. It uses virtual addresses regardless of -use_physical. "
"The dynamic (pre-filtered) per-thread instruction count is tracked and supplied "
"via a #TRACE_MARKER_TYPE_INSTRUCTION_COUNT marker at thread exit.");

droption_t<bytesize_t> op_L0I_size(
DROPTION_SCOPE_CLIENT, "L0I_size", 32 * 1024U,
Expand Down Expand Up @@ -327,6 +327,9 @@ droption_t<bool>
#ifdef DEBUG
droption_t<bool> op_test_mode(DROPTION_SCOPE_ALL, "test_mode", false, "Run sanity tests",
"Run extra analyses for sanity checks on the trace.");
droption_t<std::string> op_test_mode_name(
DROPTION_SCOPE_ALL, "test_mode_name", "", "Run custom sanity tests",
"Run extra analyses for specific sanity checks by name on the trace.");
#endif
droption_t<bool> op_disable_optimizations(
DROPTION_SCOPE_ALL, "disable_optimizations", false,
Expand Down
3 changes: 2 additions & 1 deletion clients/drcachesim/common/options.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2015-2020 Google, Inc. All rights reserved.
* Copyright (c) 2015-2021 Google, Inc. All rights reserved.
* **********************************************************/

/*
Expand Down Expand Up @@ -106,6 +106,7 @@ extern droption_t<bool> op_show_func_trace;
extern droption_t<int> op_jobs;
#ifdef DEBUG
extern droption_t<bool> op_test_mode;
extern droption_t<std::string> op_test_mode_name;
#endif
extern droption_t<bool> op_disable_optimizations;
extern droption_t<std::string> op_dr_root;
Expand Down
12 changes: 10 additions & 2 deletions clients/drcachesim/common/trace_entry.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2015-2020 Google, Inc. All rights reserved.
* Copyright (c) 2015-2021 Google, Inc. All rights reserved.
* **********************************************************/

/*
Expand Down Expand Up @@ -280,6 +280,13 @@ typedef enum {
*/
TRACE_MARKER_TYPE_CACHE_LINE_SIZE,

/**
* The marker value contains the count of dynamic instruction executions in
* this software thread since the start of the trace. This marker type is only
* present in online-cache-filtered traces and is placed at thread exit.
*/
TRACE_MARKER_TYPE_INSTRUCTION_COUNT,

// ...
// These values are reserved for future built-in marker types.
// ...
Expand Down Expand Up @@ -403,7 +410,8 @@ typedef enum {

/**
* Bitfields used to describe the high-level characteristics of both an
* offline final trace and a raw not-yet-postprocessed trace.
* offline final trace and a raw not-yet-postprocessed trace, as well as
* (despite the OFFLINE_ prefix) an online trace.
* In a final trace these are stored in a marker of type #TRACE_MARKER_TYPE_FILETYPE.
*/
typedef enum {
Expand Down
4 changes: 4 additions & 0 deletions clients/drcachesim/drcachesim.dox.in
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,10 @@ closely match the actual hardware if so desired.
Traces also include markers indicating disruptions in user mode control
flow such as signal handler entry and exit.

Filtered traces (filtered via -L0_filter) include the dynamic (pre-filtered)
per-thread instruction count in a #TRACE_MARKER_TYPE_INSTRUCTION_COUNT marker at
thread exit.

A final feature that aids core simulators is the pair of interfaces
module_mapper_t::get_loaded_modules() and
module_mapper_t::find_mapped_trace_address(), which facilitate reading the raw
Expand Down
39 changes: 39 additions & 0 deletions clients/drcachesim/tests/filter-asm.templatex
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
---- <application exited with code 0> ----
Cache simulation results:
Core #0 \(1 thread\(s\)\)
L1I stats:
Hits: 0
Misses: .*
Invalidations: 0
Miss rate: 100.00%
L1D stats:
Hits: 0
Misses: 0
Invalidations: 0
Core #1 \(0 thread\(s\)\)
Core #2 \(0 thread\(s\)\)
Core #3 \(0 thread\(s\)\)
LL stats:
Hits: 0
Misses: .*
Invalidations: 0
Miss rate: 100.00%

===========================================================================
Trace invariant checks passed
5 changes: 4 additions & 1 deletion clients/drcachesim/tests/filter-no-d.templatex
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ LL stats:
Invalidations: *0
.* Local miss rate: *[0-9,.]*%
Child hits: *[0-9,\.]*
Total miss rate: *[1-9]?[0-9][,\.]..%
Total miss rate: *[1-9]?[0-9][,\.]..%(

===========================================================================
Trace invariant checks passed)?
5 changes: 4 additions & 1 deletion clients/drcachesim/tests/filter-no-i.templatex
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ LL stats:
Invalidations: *0
.* Local miss rate: *[0-9,.]*%
Child hits: *[0-9,\.]*
Total miss rate: *[1-9]?[0-9][,\.]..%
Total miss rate: *[1-9]?[0-9][,\.]..%(

===========================================================================
Trace invariant checks passed)?
5 changes: 4 additions & 1 deletion clients/drcachesim/tests/filter-simple.templatex
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ LL stats:
Invalidations: *0
.* Local miss rate: *[0-9,.]*%
Child hits: *[0-9,\.]*
Total miss rate: *[1-9]?[0-9][,\.]..%
Total miss rate: *[1-9]?[0-9][,\.]..%(

===========================================================================
Trace invariant checks passed)?
26 changes: 23 additions & 3 deletions clients/drcachesim/tests/trace_invariants.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2017-2020 Google, Inc. All rights reserved.
* Copyright (c) 2017-2021 Google, Inc. All rights reserved.
* **********************************************************/

/*
Expand Down Expand Up @@ -35,9 +35,11 @@
#include <iostream>
#include <string.h>

trace_invariants_t::trace_invariants_t(bool offline, unsigned int verbose)
trace_invariants_t::trace_invariants_t(bool offline, unsigned int verbose,
std::string test_name)
: knob_offline_(offline)
, knob_verbose_(verbose)
, knob_test_name_(test_name)
, instrs_until_interrupt_(-1)
, memrefs_until_interrupt_(-1)
, app_handler_pc_(0)
Expand Down Expand Up @@ -83,12 +85,28 @@ trace_invariants_t::process_memref(const memref_t &memref)
app_handler_pc_ = prev_entry_.instr.addr;
}

if (memref.marker.type == TRACE_TYPE_MARKER &&
memref.marker.marker_type == TRACE_MARKER_TYPE_FILETYPE) {
file_type_ = static_cast<offline_file_type_t>(memref.marker.marker_value);
}
if (memref.marker.type == TRACE_TYPE_MARKER &&
memref.marker.marker_type == TRACE_MARKER_TYPE_INSTRUCTION_COUNT) {
found_instr_count_marker_[memref.marker.tid] = true;
if (knob_test_name_ == "filter_asm_instr_count") {
#ifndef NDEBUG
static constexpr int ASM_INSTR_COUNT = 133;
#endif
assert(memref.marker.marker_value == ASM_INSTR_COUNT);
}
}
if (memref.marker.type == TRACE_TYPE_MARKER &&
memref.marker.marker_type == TRACE_MARKER_TYPE_CACHE_LINE_SIZE) {
found_cache_line_size_marker_[memref.marker.tid] = true;
}

if (memref.exit.type == TRACE_TYPE_THREAD_EXIT) {
assert(!TESTALL(OFFLINE_FILE_TYPE_FILTERED, file_type_) ||
found_instr_count_marker_[memref.exit.tid]);
assert(found_cache_line_size_marker_[memref.exit.tid]);
thread_exited_[memref.exit.tid] = true;
}
Expand Down Expand Up @@ -122,7 +140,9 @@ trace_invariants_t::process_memref(const memref_t &memref)
if (prev_instr_.instr.addr != 0 /*first*/ &&
prev_instr_.instr.tid == memref.instr.tid &&
!type_is_instr_branch(prev_instr_.instr.type)) {
assert( // Regular fall-through.
assert( // Filtered.
TESTALL(OFFLINE_FILE_TYPE_FILTERED, file_type_) ||
// Regular fall-through.
(prev_instr_.instr.addr + prev_instr_.instr.size == memref.instr.addr) ||
// String loop.
(prev_instr_.instr.addr == memref.instr.addr &&
Expand Down
8 changes: 6 additions & 2 deletions clients/drcachesim/tests/trace_invariants.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2016-2020 Google, Inc. All rights reserved.
* Copyright (c) 2016-2021 Google, Inc. All rights reserved.
* **********************************************************/

/*
Expand Down Expand Up @@ -42,7 +42,8 @@

class trace_invariants_t : public analysis_tool_t {
public:
trace_invariants_t(bool offline = true, unsigned int verbose = 0);
trace_invariants_t(bool offline = true, unsigned int verbose = 0,
std::string test_name = "");
virtual ~trace_invariants_t();
bool
process_memref(const memref_t &memref) override;
Expand All @@ -52,6 +53,7 @@ class trace_invariants_t : public analysis_tool_t {
protected:
bool knob_offline_;
unsigned int knob_verbose_;
std::string knob_test_name_;
memref_t prev_instr_;
memref_t prev_xfer_marker_;
memref_t prev_entry_;
Expand All @@ -60,8 +62,10 @@ class trace_invariants_t : public analysis_tool_t {
int instrs_until_interrupt_;
int memrefs_until_interrupt_;
addr_t app_handler_pc_;
offline_file_type_t file_type_ = OFFLINE_FILE_TYPE_DEFAULT;
std::unordered_map<memref_tid_t, bool> thread_exited_;
std::unordered_map<memref_tid_t, bool> found_cache_line_size_marker_;
std::unordered_map<memref_tid_t, bool> found_instr_count_marker_;
};

#endif /* _TRACE_INVARIANTS_H_ */
4 changes: 3 additions & 1 deletion clients/drcachesim/tracer/instru.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2016-2020 Google, Inc. All rights reserved.
* Copyright (c) 2016-2021 Google, Inc. All rights reserved.
* **********************************************************/

/*
Expand Down Expand Up @@ -312,6 +312,8 @@ class online_instru_t : public instru_t {
append_iflush(byte *buf_ptr, addr_t start, size_t size) override;
int
append_thread_header(byte *buf_ptr, thread_id_t tid) override;
virtual int
append_thread_header(byte *buf_ptr, thread_id_t tid, offline_file_type_t file_type);
int
append_unit_header(byte *buf_ptr, thread_id_t tid) override;

Expand Down
12 changes: 10 additions & 2 deletions clients/drcachesim/tracer/instru_online.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* **********************************************************
* Copyright (c) 2016-2020 Google, Inc. All rights reserved.
* Copyright (c) 2016-2021 Google, Inc. All rights reserved.
* **********************************************************/

/*
Expand Down Expand Up @@ -138,17 +138,25 @@ online_instru_t::append_iflush(byte *buf_ptr, addr_t start, size_t size)
}

int
online_instru_t::append_thread_header(byte *buf_ptr, thread_id_t tid)
online_instru_t::append_thread_header(byte *buf_ptr, thread_id_t tid,
offline_file_type_t file_type)
{
byte *new_buf = buf_ptr;
new_buf += append_tid(new_buf, tid);
new_buf += append_pid(new_buf, dr_get_process_id());

new_buf += append_marker(new_buf, TRACE_MARKER_TYPE_FILETYPE, file_type);
new_buf += append_marker(new_buf, TRACE_MARKER_TYPE_CACHE_LINE_SIZE,
proc_get_cache_line_size());
return (int)(new_buf - buf_ptr);
}

int
online_instru_t::append_thread_header(byte *buf_ptr, thread_id_t tid)
{
return append_thread_header(buf_ptr, tid, OFFLINE_FILE_TYPE_DEFAULT);
}

int
online_instru_t::append_unit_header(byte *buf_ptr, thread_id_t tid)
{
Expand Down
Loading

0 comments on commit c530f52

Please sign in to comment.