Use group leader fd
Events in the same group should be associated with the same set of instructions
This commit is contained in:
@@ -171,7 +171,8 @@ double toSeconds(timeval t) {
|
|||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <linux/perf_event.h>
|
#include <linux/perf_event.h>
|
||||||
struct PerfCounter {
|
struct PerfCounter {
|
||||||
PerfCounter(int type, int config, const std::string &labels = {})
|
PerfCounter(int type, int config, const std::string &labels = {},
|
||||||
|
int groupLeaderFd = -1)
|
||||||
: labels(labels) {
|
: labels(labels) {
|
||||||
struct perf_event_attr pe;
|
struct perf_event_attr pe;
|
||||||
|
|
||||||
@@ -183,7 +184,7 @@ struct PerfCounter {
|
|||||||
pe.exclude_kernel = 1;
|
pe.exclude_kernel = 1;
|
||||||
pe.exclude_hv = 1;
|
pe.exclude_hv = 1;
|
||||||
|
|
||||||
fd = perf_event_open(&pe, 0, -1, -1, 0);
|
fd = perf_event_open(&pe, 0, -1, groupLeaderFd, 0);
|
||||||
if (fd < 0 && errno != ENOENT && errno != EINVAL) {
|
if (fd < 0 && errno != ENOENT && errno != EINVAL) {
|
||||||
perror(labels.c_str());
|
perror(labels.c_str());
|
||||||
}
|
}
|
||||||
@@ -214,6 +215,7 @@ struct PerfCounter {
|
|||||||
|
|
||||||
bool ok() const { return fd >= 0; }
|
bool ok() const { return fd >= 0; }
|
||||||
const std::string &getLabels() const { return labels; }
|
const std::string &getLabels() const { return labels; }
|
||||||
|
int getFd() const { return fd; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int fd;
|
int fd;
|
||||||
@@ -246,7 +248,8 @@ int main(int argc, char **argv) {
|
|||||||
cs.getMetricsV1(&metrics, &metricsCount);
|
cs.getMetricsV1(&metrics, &metricsCount);
|
||||||
|
|
||||||
PerfCounter instructions{PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS};
|
PerfCounter instructions{PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS};
|
||||||
PerfCounter cycles{PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES};
|
PerfCounter cycles{PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES, "",
|
||||||
|
instructions.getFd()};
|
||||||
|
|
||||||
std::vector<PerfCounter> cacheCounters;
|
std::vector<PerfCounter> cacheCounters;
|
||||||
for (auto [id, idStr] : std::initializer_list<std::pair<int, std::string>>{
|
for (auto [id, idStr] : std::initializer_list<std::pair<int, std::string>>{
|
||||||
@@ -265,6 +268,7 @@ int main(int argc, char **argv) {
|
|||||||
{PERF_COUNT_HW_CACHE_OP_WRITE, "write"},
|
{PERF_COUNT_HW_CACHE_OP_WRITE, "write"},
|
||||||
{PERF_COUNT_HW_CACHE_OP_PREFETCH, "prefetch"},
|
{PERF_COUNT_HW_CACHE_OP_PREFETCH, "prefetch"},
|
||||||
}) {
|
}) {
|
||||||
|
int groupLeaderFd = -1;
|
||||||
for (auto [result, resultStr] :
|
for (auto [result, resultStr] :
|
||||||
std::initializer_list<std::pair<int, std::string>>{
|
std::initializer_list<std::pair<int, std::string>>{
|
||||||
{PERF_COUNT_HW_CACHE_RESULT_MISS, "miss"},
|
{PERF_COUNT_HW_CACHE_RESULT_MISS, "miss"},
|
||||||
@@ -273,9 +277,14 @@ int main(int argc, char **argv) {
|
|||||||
auto labels = "{id=\"" + idStr + "\", op=\"" + opStr +
|
auto labels = "{id=\"" + idStr + "\", op=\"" + opStr +
|
||||||
"\", result=\"" + resultStr + "\"}";
|
"\", result=\"" + resultStr + "\"}";
|
||||||
cacheCounters.emplace_back(PERF_TYPE_HW_CACHE,
|
cacheCounters.emplace_back(PERF_TYPE_HW_CACHE,
|
||||||
id | (op << 8) | (result << 16), labels);
|
id | (op << 8) | (result << 16), labels,
|
||||||
|
groupLeaderFd);
|
||||||
if (!cacheCounters.back().ok()) {
|
if (!cacheCounters.back().ok()) {
|
||||||
cacheCounters.pop_back();
|
cacheCounters.pop_back();
|
||||||
|
} else {
|
||||||
|
if (groupLeaderFd == -1) {
|
||||||
|
groupLeaderFd = cacheCounters.back().getFd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user