8#ifdef QTESTLIB_USE_PERF_EVENTS
12#include "../corelib/kernel/qcore_unix_p.h"
22#include <sys/syscall.h>
24#include "3rdparty/linux_perf_event_p.h"
30#define CACHE_L1D_READ (PERF_COUNT_HW_CACHE_L1D | PERF_COUNT_HW_CACHE_OP_READ << 8 | PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
31#define CACHE_L1D_WRITE (PERF_COUNT_HW_CACHE_L1D | PERF_COUNT_HW_CACHE_OP_WRITE << 8 | PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
32#define CACHE_L1D_PREFETCH (PERF_COUNT_HW_CACHE_L1D | PERF_COUNT_HW_CACHE_OP_PREFETCH << 8 | PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
33#define CACHE_L1I_READ (PERF_COUNT_HW_CACHE_L1I | PERF_COUNT_HW_CACHE_OP_READ << 8 | PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
34#define CACHE_L1I_PREFETCH (PERF_COUNT_HW_CACHE_L1I | PERF_COUNT_HW_CACHE_OP_PREFETCH << 8 | PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
35#define CACHE_LLC_READ (PERF_COUNT_HW_CACHE_LL | PERF_COUNT_HW_CACHE_OP_READ << 8 | PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
36#define CACHE_LLC_WRITE (PERF_COUNT_HW_CACHE_LL | PERF_COUNT_HW_CACHE_OP_WRITE << 8| PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
37#define CACHE_LLC_PREFETCH (PERF_COUNT_HW_CACHE_LL | PERF_COUNT_HW_CACHE_OP_PREFETCH << 8 | PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
38#define CACHE_L1D_READ_MISS (PERF_COUNT_HW_CACHE_L1D | PERF_COUNT_HW_CACHE_OP_READ << 8 | PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
39#define CACHE_L1D_WRITE_MISS (PERF_COUNT_HW_CACHE_L1D | PERF_COUNT_HW_CACHE_OP_WRITE << 8 | PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
40#define CACHE_L1D_PREFETCH_MISS (PERF_COUNT_HW_CACHE_L1D | PERF_COUNT_HW_CACHE_OP_PREFETCH << 8 | PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
41#define CACHE_L1I_READ_MISS (PERF_COUNT_HW_CACHE_L1I | PERF_COUNT_HW_CACHE_OP_READ << 8 | PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
42#define CACHE_L1I_PREFETCH_MISS (PERF_COUNT_HW_CACHE_L1I | PERF_COUNT_HW_CACHE_OP_PREFETCH << 8 | PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
43#define CACHE_LLC_READ_MISS (PERF_COUNT_HW_CACHE_LL | PERF_COUNT_HW_CACHE_OP_READ << 8 | PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
44#define CACHE_LLC_WRITE_MISS (PERF_COUNT_HW_CACHE_LL | PERF_COUNT_HW_CACHE_OP_WRITE << 8 | PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
45#define CACHE_LLC_PREFETCH_MISS (PERF_COUNT_HW_CACHE_LL | PERF_COUNT_HW_CACHE_OP_PREFETCH << 8 | PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
46#define CACHE_BRANCH_READ (PERF_COUNT_HW_CACHE_BPU | PERF_COUNT_HW_CACHE_OP_READ << 8 | PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16)
47#define CACHE_BRANCH_READ_MISS (PERF_COUNT_HW_CACHE_BPU | PERF_COUNT_HW_CACHE_OP_READ << 8 | PERF_COUNT_HW_CACHE_RESULT_MISS << 16)
56static perf_event_attr attr;
63 memset(&attr, 0,
sizeof attr);
64 attr.size =
sizeof attr;
65 attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING;
69 attr.inherit_stat =
true;
79 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
80 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES },
81 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS },
82 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
108static int perf_event_open(perf_event_attr *attr, pid_t pid,
int cpu,
int group_fd,
unsigned long flags)
110#ifdef SYS_perf_event_open
112 return int(syscall(SYS_perf_event_open, attr, pid, cpu, group_fd,
flags));
128 return perf_event_open(
nullptr, 0, 0, 0, 0) == -1 && errno != ENOSYS;
224static const char eventlist_strings[] =
226 "branch-instructions\0"
227 "branch-load-misses\0"
229 "branch-mispredicts\0"
232 "branch-read-misses\0"
246 "idle-cycles-backend\0"
247 "idle-cycles-frontend\0"
249 "l1d-cache-load-misses\0"
251 "l1d-cache-prefetch-misses\0"
252 "l1d-cache-prefetches\0"
253 "l1d-cache-read-misses\0"
255 "l1d-cache-store-misses\0"
257 "l1d-cache-write-misses\0"
261 "l1d-prefetch-misses\0"
269 "l1i-cache-load-misses\0"
271 "l1i-cache-prefetch-misses\0"
272 "l1i-cache-prefetches\0"
273 "l1i-cache-read-misses\0"
277 "l1i-prefetch-misses\0"
281 "llc-cache-load-misses\0"
283 "llc-cache-prefetch-misses\0"
284 "llc-cache-prefetches\0"
285 "llc-cache-read-misses\0"
287 "llc-cache-store-misses\0"
289 "llc-cache-write-misses\0"
293 "llc-prefetch-misses\0"
306 "stalled-cycles-backend\0"
307 "stalled-cycles-frontend\0"
311static const Events eventlist[] = {
401 for (
const Events &ev : eventlist) {
416 while (!
input.empty()) {
417 std::string_view countername =
input;
418 if (
qsizetype idx = countername.find(
','); idx >= 0)
419 countername = countername.substr(0, idx);
421 for (
const Events &ev : eventlist) {
422 int c = countername.compare(eventlist_strings + ev.offset);
426 fprintf(stderr,
"ERROR: Performance counter type '%.*s' is unknown\n",
427 int(countername.size()), countername.data());
430 eventTypes->append({ ev.type, ev.event_id });
434 if (countername.size() ==
input.size())
437 input.remove_prefix(countername.size() + 1);
449 printf(
"Performance counters are not available on this system\n");
453 printf(
"The following performance counters are available:\n");
454 for (
const Events &ev : eventlist) {
455 printf(
" %-30s [%s]\n", eventlist_strings + ev.offset,
456 ev.type == PERF_TYPE_HARDWARE ?
"hardware" :
457 ev.
type == PERF_TYPE_SOFTWARE ?
"software" :
458 ev.
type == PERF_TYPE_HW_CACHE ?
"cache" :
"other");
484 int flags = PERF_FLAG_FD_CLOEXEC;
490 int fd = perf_event_open(&attr, pid, cpu, group_fd,
flags);
493 attr.exclude_kernel =
true;
494 attr.exclude_hv =
true;
495 fd = perf_event_open(&attr, pid, cpu, group_fd,
flags);
498 perror(
"QBenchmarkPerfEventsMeasurer::start: perf_event_open");
508 ::ioctl(
fd, PERF_EVENT_IOC_RESET);
509 prctl(PR_TASK_PERF_EVENTS_ENABLE);
515 prctl(PR_TASK_PERF_EVENTS_DISABLE);
558 while (nread <
sizeof results) {
559 char *
ptr =
reinterpret_cast<char *
>(&
results);
562 perror(
"QBenchmarkPerfEventsMeasurer::readValue: reading the results");
578 return {
qreal(
qint64(raw)), metricForEvent(eventTypes->at(idx)) };
int adjustIterationCount(int suggestion) override
QBenchmarkPerfEventsMeasurer()
QList< Measurement > stop() override
static void listCounters()
int adjustMedianCount(int suggestion) override
static bool isAvailable()
~QBenchmarkPerfEventsMeasurer()
static void setCounter(const char *name)
bool isMeasurementAccepted(Measurement measurement) override
T value(qsizetype i) const
EGLint EGLint EGLint EGLint int int int int * fds
Combined button and popup list for selecting options.
static qint64 qt_safe_read(int fd, void *data, qint64 maxlen)
static int qt_safe_close(int fd)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
static ControlElement< T > * ptr(QWidget *widget)
GLint GLint GLsizei GLuint * counters
GLenum GLuint GLintptr offset
GLenum GLenum GLenum input
unsigned long long quint64