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
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:
@@ -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 ";
|
||||
|
Reference in New Issue
Block a user