Add several new cache events to metrics
All checks were successful
Tests / Clang total: 2500, passed: 2500
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 2498, passed: 2498
Tests / SIMD fallback total: 2500, passed: 2500
Tests / Release [gcc] total: 2500, passed: 2500
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1867, passed: 1867
Tests / Coverage total: 1877, passed: 1877
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 99.29% (1829/1842) * Branch Coverage: 67.35% (1479/2196) * Complexity Density: 0.00 * Lines of Code: 1842 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head This commit looks good

This commit is contained in:
2024-08-16 12:48:22 -07:00
parent b15959d62c
commit ce54746a4a

View File

@@ -11,6 +11,8 @@
#include <sys/uio.h>
#include <thread>
#include <unistd.h>
#include <utility>
#include <vector>
#include "ConflictSet.h"
#include "third_party/nadeau.h"
@@ -175,25 +177,22 @@ double toSeconds(timeval t) {
#ifdef __linux__
struct PerfCounter {
PerfCounter(int type, int event) {
PerfCounter(int type, int config, const std::string &labels = {})
: labels(labels) {
struct perf_event_attr pe;
memset(&pe, 0, sizeof(pe));
pe.type = PERF_TYPE_HARDWARE;
pe.type = type;
pe.size = sizeof(pe);
pe.config = event;
pe.config = config;
pe.inherit = 1;
pe.exclude_kernel = 1;
pe.exclude_hv = 1;
fd = perf_event_open(&pe, 0, -1, -1, 0);
if (fd == -1) {
fprintf(stderr, "Error opening leader %llx\n", pe.config);
exit(EXIT_FAILURE);
}
}
int64_t total() {
int64_t total() const {
int64_t count;
if (read(fd, &count, sizeof(count)) != sizeof(count)) {
perror("read instructions from perf");
@@ -202,10 +201,26 @@ struct PerfCounter {
return count;
}
~PerfCounter() { close(fd); }
PerfCounter(PerfCounter &&other)
: fd(std::exchange(other.fd, -1)), labels(std::move(other.labels)) {}
PerfCounter &operator=(PerfCounter &&other) {
fd = std::exchange(other.fd, -1);
labels = std::move(other.labels);
return *this;
}
~PerfCounter() {
if (fd >= 0) {
close(fd);
}
}
bool ok() const { return fd >= 0; }
const std::string &getLabels() const { return labels; }
private:
int fd;
std::string labels;
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags) {
int ret;
@@ -235,10 +250,41 @@ int main(int argc, char **argv) {
PerfCounter instructions{PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS};
PerfCounter cycles{PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES};
PerfCounter cacheRef{PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES};
PerfCounter cacheMiss{PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES};
PerfCounter branch{PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS};
PerfCounter branchMiss{PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES};
std::vector<PerfCounter> cacheCounters;
for (auto [id, idStr] : std::initializer_list<std::pair<int, std::string>>{
{PERF_COUNT_HW_CACHE_L1D, "l1d"},
{PERF_COUNT_HW_CACHE_L1I, "l1i"},
{PERF_COUNT_HW_CACHE_LL, "ll"},
{PERF_COUNT_HW_CACHE_DTLB, "dtlb"},
// Somehow was showing a miss rate > 1 /shrug
// {PERF_COUNT_HW_CACHE_ITLB, "itlb"},
{PERF_COUNT_HW_CACHE_BPU, "bpu"},
{PERF_COUNT_HW_CACHE_NODE, "node"},
}) {
for (auto [op, opStr] :
std::initializer_list<std::pair<int, std::string>>{
{PERF_COUNT_HW_CACHE_OP_READ, "read"},
{PERF_COUNT_HW_CACHE_OP_WRITE, "write"},
{PERF_COUNT_HW_CACHE_OP_PREFETCH, "prefetch"},
}) {
for (auto [result, resultStr] :
std::initializer_list<std::pair<int, std::string>>{
{PERF_COUNT_HW_CACHE_RESULT_MISS, "miss"},
{PERF_COUNT_HW_CACHE_RESULT_ACCESS, "access"},
}) {
auto labels = "{id=\"" + idStr + "\", op=\"" + opStr +
"\", result=\"" + resultStr + "\"}";
cacheCounters.emplace_back(PERF_TYPE_HW_CACHE,
id | (op << 8) | (result << 16), labels);
if (!cacheCounters.back().ok()) {
fprintf(stderr, "Could not open cache event: %s\n", labels.c_str());
cacheCounters.pop_back();
}
}
}
}
auto w = std::thread{workload, &cs};
for (;;) {
@@ -276,26 +322,12 @@ int main(int argc, char **argv) {
"cycles_total ";
body += std::to_string(cycles.total());
body += "\n";
body += "# HELP cache_references_total Total number of cache references\n"
"# TYPE cache_references_total counter\n"
"cache_references_total ";
body += std::to_string(cacheRef.total());
body += "\n";
body += "# HELP cache_misses_total Total number of cache misses\n"
"# TYPE cache_misses_total counter\n"
"cache_misses_total ";
body += std::to_string(cacheMiss.total());
body += "\n";
body += "# HELP branch_instructions_total Total number of branch "
"instructions\n"
"# TYPE branch_instructions_total counter\n"
"branch_instructions_total ";
body += std::to_string(branch.total());
body += "\n";
body += "# HELP branch_misses_total Total number of branch misses\n"
"# TYPE branch_misses_total counter\n"
"branch_misses_total ";
body += std::to_string(branchMiss.total());
body += "# HELP cache_event_total Total number of cache events\n"
"# TYPE cache_event_total counter\n";
for (const auto &counter : cacheCounters) {
body += "cache_event_total" + counter.getLabels() + " " +
std::to_string(counter.total()) + "\n";
}
for (int i = 0; i < metricsCount; ++i) {
body += "# HELP ";