Skip to content

Commit c1ae794

Browse files
i#8026 histogram cleanup: Remove shifts from histogram map (#8033)
Removes the pointless shifts of addresses into cache lines in the drmemtrace histogram tool, as it's using a map in any case. Also stops printing if there are fewer results than the requested count. Adds a test of this. Finally, makes cmp() and back_align() class functions so they can be used in subclasses. Fixes #8026
1 parent f88e38a commit c1ae794

3 files changed

Lines changed: 67 additions & 29 deletions

File tree

clients/drcachesim/tests/histogram_test.cpp

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838

3939
#include <iostream>
4040
#include <optional>
41+
#include <regex>
42+
#include <sstream>
4143
#include <vector>
4244

4345
#include "../tools/histogram.h"
@@ -84,9 +86,7 @@ bool
8486
check_parallel_reduce()
8587
{
8688
static constexpr unsigned int LINE_SIZE = 64;
87-
// XXX i#8026: Remove this shift to simplify storage.
88-
static constexpr unsigned int LINE_SHIFT = 6;
89-
histogram_t tool(LINE_SIZE, /*report_top=*/5, /*verbose=*/0);
89+
histogram_t tool(LINE_SIZE, /*report_top=*/10, /*verbose=*/0);
9090
std::vector<memref_t> memrefs = {
9191
gen_instr(1, 20 * LINE_SIZE),
9292
gen_data(1, /*load=*/true, 10 * LINE_SIZE, 8),
@@ -120,23 +120,52 @@ check_parallel_reduce()
120120
std::cerr << "failed to obtain icache counts\n";
121121
return false;
122122
}
123-
// XXX i#8026: Remove this shift to simplify storage.
124-
if ((*icache_res)[(20 * LINE_SIZE) >> LINE_SHIFT] != 2 ||
125-
(*icache_res)[(21 * LINE_SIZE) >> LINE_SHIFT] != 1) {
126-
std::cerr << "incorrect icache counts: got "
127-
<< (*icache_res)[(20 * LINE_SIZE) >> LINE_SHIFT] << ","
128-
<< (*icache_res)[(21 * LINE_SIZE) >> LINE_SHIFT]
129-
<< " instead of 2,1\n";
123+
if ((*icache_res)[20 * LINE_SIZE] != 2 || (*icache_res)[21 * LINE_SIZE] != 1) {
124+
std::cerr << "incorrect icache counts: got " << (*icache_res)[20 * LINE_SIZE]
125+
<< "," << (*icache_res)[21 * LINE_SIZE] << " instead of 2,1\n";
130126
return false;
131127
}
132128
return true;
133129
};
134130
if (!check_icache())
135131
return false;
132+
136133
// Do another reduce inside print_results, testing that multiple reduces
137134
// do not change the result. The get_icache_counts() will also do another
138135
// reduce.
136+
// While at it, we test that printing stops before hitting the 10 top
137+
// results we requested when there aren't 10 total.
138+
std::stringstream capture;
139+
std::streambuf *prior = std::cerr.rdbuf(capture.rdbuf());
139140
tool.print_results();
141+
std::string res = capture.str();
142+
std::cerr.rdbuf(prior);
143+
// The order of same-count items can vary so we use a regex.
144+
const char *expect = R"DELIM(Cache line histogram tool results:
145+
icache: 5 unique cache lines
146+
dcache: 8 unique cache lines
147+
icache top 10
148+
0x500: 2
149+
0x..0: 1
150+
0x..0: 1
151+
0x..0: 1
152+
0x..0: 1
153+
dcache top 10
154+
0x280: 2
155+
0x..0: 1
156+
0x..0: 1
157+
0x..0: 1
158+
0x..0: 1
159+
0x..0: 1
160+
0x..0: 1
161+
0x..0: 1
162+
)DELIM";
163+
if (!std::regex_search(res, std::regex(expect))) {
164+
std::cerr << "print_results output |" << res << "| did not match expected |"
165+
<< expect << "\n";
166+
return false;
167+
}
168+
140169
if (!check_icache())
141170
return false;
142171
return true;

clients/drcachesim/tools/histogram.cpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ histogram_t::histogram_t(unsigned int line_size, unsigned int report_top,
6666
: knob_line_size_(line_size)
6767
, knob_report_top_(report_top)
6868
{
69-
line_size_bits_ = compute_log2((int)line_size);
7069
}
7170

7271
histogram_t::~histogram_t()
@@ -110,12 +109,6 @@ histogram_t::parallel_shard_exit(void *shard_data)
110109
return true;
111110
}
112111

113-
static inline addr_t
114-
back_align(addr_t addr, addr_t align)
115-
{
116-
return addr & ~(align - 1);
117-
}
118-
119112
bool
120113
histogram_t::parallel_shard_memref(void *shard_data, const memref_t &memref)
121114
{
@@ -141,8 +134,7 @@ histogram_t::parallel_shard_memref(void *shard_data, const memref_t &memref)
141134
for (addr_t addr = back_align(start_addr, knob_line_size_);
142135
addr < start_addr + size && addr < addr + knob_line_size_ /* overflow */;
143136
addr += knob_line_size_) {
144-
// XXX i#8026: Remove this shift to simplify storage.
145-
++(*cache_map)[addr >> line_size_bits_];
137+
++(*cache_map)[addr];
146138
}
147139
return true;
148140
}
@@ -165,7 +157,8 @@ histogram_t::process_memref(const memref_t &memref)
165157
}
166158

167159
bool
168-
cmp(const std::pair<addr_t, uint64_t> &l, const std::pair<addr_t, uint64_t> &r)
160+
histogram_t::cmp(const std::pair<addr_t, uint64_t> &l,
161+
const std::pair<addr_t, uint64_t> &r)
169162
{
170163
return l.second > r.second;
171164
}
@@ -228,20 +221,28 @@ histogram_t::print_results()
228221
std::partial_sort_copy(reduced_.icache_map.begin(), reduced_.icache_map.end(),
229222
top.begin(), top.end(), cmp);
230223
std::cerr << "icache top " << top.size() << "\n";
231-
for (std::vector<std::pair<addr_t, uint64_t>>::iterator it = top.begin();
232-
it != top.end(); ++it) {
233-
std::cerr << std::setw(18) << std::hex << std::showbase << (it->first << 6)
234-
<< ": " << std::dec << it->second << "\n";
224+
for (const auto &[addr, count] : top) {
225+
if (count == 0) {
226+
// If total observed elements are fewer than knob_report_top_, avoid
227+
// printing lines of 0's.
228+
break;
229+
}
230+
std::cerr << std::setw(18) << std::hex << std::showbase << addr << ": "
231+
<< std::dec << count << "\n";
235232
}
236233
top.clear();
237234
top.resize(knob_report_top_);
238235
std::partial_sort_copy(reduced_.dcache_map.begin(), reduced_.dcache_map.end(),
239236
top.begin(), top.end(), cmp);
240237
std::cerr << "dcache top " << top.size() << "\n";
241-
for (std::vector<std::pair<addr_t, uint64_t>>::iterator it = top.begin();
242-
it != top.end(); ++it) {
243-
std::cerr << std::setw(18) << std::hex << std::showbase << (it->first << 6)
244-
<< ": " << std::dec << it->second << "\n";
238+
for (const auto &[addr, count] : top) {
239+
if (count == 0) {
240+
// If total observed elements are fewer than knob_report_top_, avoid
241+
// printing lines of 0's.
242+
break;
243+
}
244+
std::cerr << std::setw(18) << std::hex << std::showbase << addr << ": "
245+
<< std::dec << count << "\n";
245246
}
246247
// Reset the i/o format for subsequent tool invocations.
247248
std::cerr << std::dec;

clients/drcachesim/tools/histogram.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,17 @@ class histogram_t : public analysis_tool_t {
9292
std::string error;
9393
};
9494

95+
static bool
96+
cmp(const std::pair<addr_t, uint64_t> &l, const std::pair<addr_t, uint64_t> &r);
97+
98+
static inline addr_t
99+
back_align(addr_t addr, addr_t align)
100+
{
101+
return addr & ~(align - 1);
102+
}
103+
95104
unsigned int knob_line_size_;
96105
unsigned int knob_report_top_; /* most accessed lines */
97-
size_t line_size_bits_;
98106
static const std::string TOOL_NAME;
99107
std::unordered_map<int, shard_data_t *> shard_map_;
100108
// This mutex is only needed in parallel_shard_init. In all other accesses to

0 commit comments

Comments
 (0)