14#include "arcane/utils/IPerformanceCounterService.h"
15#include "arcane/utils/TraceAccessor.h"
16#include "arcane/utils/FatalErrorException.h"
18#include "arcane/core/FactoryService.h"
20#include <linux/perf_event.h>
21#include <linux/hw_breakpoint.h>
38class LinuxPerfPerformanceCounterService
48 ~LinuxPerfPerformanceCounterService()
63 bool _addEvent(
int event_type,
int event_config,
bool is_optional =
false)
65 struct perf_event_attr attr;
66 std::memset(&attr, 0,
sizeof(attr));
68 attr.type = event_type,
69 attr.config = event_config;
70 attr.size =
sizeof(
struct perf_event_attr);
71 attr.exclude_kernel = 1;
78 unsigned long flags = 0;
79 long long_fd = syscall(__NR_perf_event_open, &attr, m_process_id, cpu, group_fd, flags);
80 info(4) <<
"AddEvent type=" << attr.type <<
" id=" << attr.config <<
" fd=" << long_fd;
81 if (long_fd == (-1)) {
84 ARCANE_FATAL(
"ERROR for event type={0} id={1} error={2}", attr.type, attr.config, std::strerror(errno));
86 int fd =
static_cast<int>(long_fd);
87 m_events_file_descriptor.add(fd);
96 info(4) <<
"LinuxPerf: Start";
97 for (
int fd : m_events_file_descriptor) {
98 int r = ::ioctl(fd, PERF_EVENT_IOC_ENABLE);
100 ARCANE_FATAL(
"Error starting event r={0} error={1}", r, strerror(errno));
108 info(4) <<
"LinuxPerf: Stop";
109 for (
int fd : m_events_file_descriptor) {
110 int r = ::ioctl(fd, PERF_EVENT_IOC_DISABLE);
112 ARCANE_FATAL(
"Error stopping event r={0} error={1}", r, strerror(errno));
114 m_is_started =
false;
124 for (
Int32 index = 0, n = m_events_file_descriptor.size(); index < n; ++index) {
125 Int64 value = _getOneCounter(index);
126 Int64 current_value = counters[index];
127 counters[index] = (do_substract) ? value - current_value : value;
134 return _getOneCounter(0);
140 bool m_is_started =
false;
141 bool m_is_init =
false;
142 pid_t m_process_id = -1;
148 for (
int fd : m_events_file_descriptor) {
152 m_events_file_descriptor.
clear();
157 int fd = m_events_file_descriptor[index];
158 uint64_t value[1] = { 0 };
159 const size_t s =
sizeof(uint64_t);
160 size_t nb_read = ::read(fd, value, s);
166 void _checkInitialize()
171 info() <<
"Initialize LinuxPerfPerformanceCounterService";
172 m_process_id = ::getpid();
174 _addEvent(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES);
176 _addEvent(PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS);
184 const bool is_optional =
true;
187 int cache_access = (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16);
188 is_bad =
_addEvent(PERF_TYPE_HW_CACHE, PERF_COUNT_HW_CACHE_LL | cache_access, is_optional);
191 is_bad =
_addEvent(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND, is_optional);
193 _addEvent(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES, is_optional);
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro to declare an interface when registering a service.
void clear()
Removes the elements from the array.
virtual ITraceMng * traceMng() const =0
Trace manager.
IApplication * application() const
Access to the associated IApplication.
Structure containing the information to create a service.
Service creation properties.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
1D data vector with value semantics (STL style).
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro for registering a service.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
ArrayView< Int64 > Int64ArrayView
C equivalent of a 1D array of 64-bit integers.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
@ ST_Application
The service is used at the application level.
std::int32_t Int32
Signed integer type of 32 bits.