xref: /aosp_15_r20/system/extras/tests/icachetest/Profiler.cpp (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker #include "Profiler.h"
18*288bf522SAndroid Build Coastguard Worker 
19*288bf522SAndroid Build Coastguard Worker #include <stdlib.h>
20*288bf522SAndroid Build Coastguard Worker #include <string.h>
21*288bf522SAndroid Build Coastguard Worker #include <unistd.h>
22*288bf522SAndroid Build Coastguard Worker 
23*288bf522SAndroid Build Coastguard Worker #include <algorithm>
24*288bf522SAndroid Build Coastguard Worker #include <iostream>
25*288bf522SAndroid Build Coastguard Worker 
26*288bf522SAndroid Build Coastguard Worker #if defined(__linux__)
27*288bf522SAndroid Build Coastguard Worker 
28*288bf522SAndroid Build Coastguard Worker #include <sys/syscall.h>
29*288bf522SAndroid Build Coastguard Worker 
30*288bf522SAndroid Build Coastguard Worker #ifdef __ARM_ARCH
31*288bf522SAndroid Build Coastguard Worker     enum ARMv8PmuPerfTypes{
32*288bf522SAndroid Build Coastguard Worker         // Common micro-architecture events
33*288bf522SAndroid Build Coastguard Worker         ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL    = 0x01,
34*288bf522SAndroid Build Coastguard Worker         ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS    = 0x14,
35*288bf522SAndroid Build Coastguard Worker         ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS     = 0x16,
36*288bf522SAndroid Build Coastguard Worker         ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL     = 0x17,
37*288bf522SAndroid Build Coastguard Worker         ARMV8_PMUV3_PERFCTR_L2_CACHE_WB         = 0x18,
38*288bf522SAndroid Build Coastguard Worker     };
39*288bf522SAndroid Build Coastguard Worker #endif
40*288bf522SAndroid Build Coastguard Worker 
perf_event_open(struct perf_event_attr * hw_event,pid_t pid,int cpu,int group_fd,unsigned long flags)41*288bf522SAndroid Build Coastguard Worker static int perf_event_open(struct perf_event_attr* hw_event, pid_t pid,
42*288bf522SAndroid Build Coastguard Worker         int cpu, int group_fd, unsigned long flags) {
43*288bf522SAndroid Build Coastguard Worker     return syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
44*288bf522SAndroid Build Coastguard Worker }
45*288bf522SAndroid Build Coastguard Worker 
46*288bf522SAndroid Build Coastguard Worker #endif // __linux__
47*288bf522SAndroid Build Coastguard Worker 
48*288bf522SAndroid Build Coastguard Worker namespace utils {
49*288bf522SAndroid Build Coastguard Worker 
get()50*288bf522SAndroid Build Coastguard Worker Profiler& Profiler::get() noexcept {
51*288bf522SAndroid Build Coastguard Worker     static Profiler sProfiler;
52*288bf522SAndroid Build Coastguard Worker     return sProfiler;
53*288bf522SAndroid Build Coastguard Worker }
54*288bf522SAndroid Build Coastguard Worker 
Profiler()55*288bf522SAndroid Build Coastguard Worker Profiler::Profiler() noexcept {
56*288bf522SAndroid Build Coastguard Worker     std::uninitialized_fill(mCountersFd.begin(), mCountersFd.end(), -1);
57*288bf522SAndroid Build Coastguard Worker     Profiler::resetEvents(EV_CPU_CYCLES | EV_L1D_RATES | EV_BPU_RATES);
58*288bf522SAndroid Build Coastguard Worker }
59*288bf522SAndroid Build Coastguard Worker 
~Profiler()60*288bf522SAndroid Build Coastguard Worker Profiler::~Profiler() noexcept {
61*288bf522SAndroid Build Coastguard Worker     for (int fd : mCountersFd) {
62*288bf522SAndroid Build Coastguard Worker         if (fd >= 0) {
63*288bf522SAndroid Build Coastguard Worker             close(fd);
64*288bf522SAndroid Build Coastguard Worker         }
65*288bf522SAndroid Build Coastguard Worker     }
66*288bf522SAndroid Build Coastguard Worker }
67*288bf522SAndroid Build Coastguard Worker 
resetEvents(uint32_t eventMask)68*288bf522SAndroid Build Coastguard Worker uint32_t Profiler::resetEvents(uint32_t eventMask) noexcept {
69*288bf522SAndroid Build Coastguard Worker     // close all counters
70*288bf522SAndroid Build Coastguard Worker     for (int& fd : mCountersFd) {
71*288bf522SAndroid Build Coastguard Worker         if (fd >= 0) {
72*288bf522SAndroid Build Coastguard Worker             close(fd);
73*288bf522SAndroid Build Coastguard Worker             fd = -1;
74*288bf522SAndroid Build Coastguard Worker         }
75*288bf522SAndroid Build Coastguard Worker     }
76*288bf522SAndroid Build Coastguard Worker     mEnabledEvents = 0;
77*288bf522SAndroid Build Coastguard Worker 
78*288bf522SAndroid Build Coastguard Worker #if defined(__linux__)
79*288bf522SAndroid Build Coastguard Worker 
80*288bf522SAndroid Build Coastguard Worker     struct perf_event_attr pe;
81*288bf522SAndroid Build Coastguard Worker     memset(&pe, 0, sizeof(struct perf_event_attr));
82*288bf522SAndroid Build Coastguard Worker     pe.type = PERF_TYPE_HARDWARE;
83*288bf522SAndroid Build Coastguard Worker     pe.size = sizeof(struct perf_event_attr);
84*288bf522SAndroid Build Coastguard Worker     pe.config = PERF_COUNT_HW_INSTRUCTIONS;
85*288bf522SAndroid Build Coastguard Worker     pe.disabled = 1;
86*288bf522SAndroid Build Coastguard Worker     pe.exclude_kernel = 1;
87*288bf522SAndroid Build Coastguard Worker     pe.exclude_hv = 1;
88*288bf522SAndroid Build Coastguard Worker     pe.read_format = PERF_FORMAT_GROUP |
89*288bf522SAndroid Build Coastguard Worker                      PERF_FORMAT_ID |
90*288bf522SAndroid Build Coastguard Worker                      PERF_FORMAT_TOTAL_TIME_ENABLED |
91*288bf522SAndroid Build Coastguard Worker                      PERF_FORMAT_TOTAL_TIME_RUNNING;
92*288bf522SAndroid Build Coastguard Worker 
93*288bf522SAndroid Build Coastguard Worker     uint8_t count = 0;
94*288bf522SAndroid Build Coastguard Worker     int fd = perf_event_open(&pe, 0, -1, -1, 0);
95*288bf522SAndroid Build Coastguard Worker     if (fd >= 0) {
96*288bf522SAndroid Build Coastguard Worker         const int groupFd = fd;
97*288bf522SAndroid Build Coastguard Worker         mIds[INSTRUCTIONS] = count++;
98*288bf522SAndroid Build Coastguard Worker         mCountersFd[INSTRUCTIONS] = fd;
99*288bf522SAndroid Build Coastguard Worker 
100*288bf522SAndroid Build Coastguard Worker         pe.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID;
101*288bf522SAndroid Build Coastguard Worker 
102*288bf522SAndroid Build Coastguard Worker         if (eventMask & EV_CPU_CYCLES) {
103*288bf522SAndroid Build Coastguard Worker             pe.type = PERF_TYPE_HARDWARE;
104*288bf522SAndroid Build Coastguard Worker             pe.config = PERF_COUNT_HW_CPU_CYCLES;
105*288bf522SAndroid Build Coastguard Worker             mCountersFd[CPU_CYCLES] = perf_event_open(&pe, 0, -1, groupFd, 0);
106*288bf522SAndroid Build Coastguard Worker             if (mCountersFd[CPU_CYCLES] > 0) {
107*288bf522SAndroid Build Coastguard Worker                 mIds[CPU_CYCLES] = count++;
108*288bf522SAndroid Build Coastguard Worker                 mEnabledEvents |= EV_CPU_CYCLES;
109*288bf522SAndroid Build Coastguard Worker             }
110*288bf522SAndroid Build Coastguard Worker         }
111*288bf522SAndroid Build Coastguard Worker 
112*288bf522SAndroid Build Coastguard Worker         if (eventMask & EV_L1D_REFS) {
113*288bf522SAndroid Build Coastguard Worker             pe.type = PERF_TYPE_HARDWARE;
114*288bf522SAndroid Build Coastguard Worker             pe.config = PERF_COUNT_HW_CACHE_REFERENCES;
115*288bf522SAndroid Build Coastguard Worker             mCountersFd[DCACHE_REFS] = perf_event_open(&pe, 0, -1, groupFd, 0);
116*288bf522SAndroid Build Coastguard Worker             if (mCountersFd[DCACHE_REFS] > 0) {
117*288bf522SAndroid Build Coastguard Worker                 mIds[DCACHE_REFS] = count++;
118*288bf522SAndroid Build Coastguard Worker                 mEnabledEvents |= EV_L1D_REFS;
119*288bf522SAndroid Build Coastguard Worker             }
120*288bf522SAndroid Build Coastguard Worker         }
121*288bf522SAndroid Build Coastguard Worker 
122*288bf522SAndroid Build Coastguard Worker         if (eventMask & EV_L1D_MISSES) {
123*288bf522SAndroid Build Coastguard Worker             pe.type = PERF_TYPE_HARDWARE;
124*288bf522SAndroid Build Coastguard Worker             pe.config = PERF_COUNT_HW_CACHE_MISSES;
125*288bf522SAndroid Build Coastguard Worker             mCountersFd[DCACHE_MISSES] = perf_event_open(&pe, 0, -1, groupFd, 0);
126*288bf522SAndroid Build Coastguard Worker             if (mCountersFd[DCACHE_MISSES] > 0) {
127*288bf522SAndroid Build Coastguard Worker                 mIds[DCACHE_MISSES] = count++;
128*288bf522SAndroid Build Coastguard Worker                 mEnabledEvents |= EV_L1D_MISSES;
129*288bf522SAndroid Build Coastguard Worker             }
130*288bf522SAndroid Build Coastguard Worker         }
131*288bf522SAndroid Build Coastguard Worker 
132*288bf522SAndroid Build Coastguard Worker         if (eventMask & EV_BPU_REFS) {
133*288bf522SAndroid Build Coastguard Worker             pe.type = PERF_TYPE_HARDWARE;
134*288bf522SAndroid Build Coastguard Worker             pe.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
135*288bf522SAndroid Build Coastguard Worker             mCountersFd[BRANCHES] = perf_event_open(&pe, 0, -1, groupFd, 0);
136*288bf522SAndroid Build Coastguard Worker             if (mCountersFd[BRANCHES] > 0) {
137*288bf522SAndroid Build Coastguard Worker                 mIds[BRANCHES] = count++;
138*288bf522SAndroid Build Coastguard Worker                 mEnabledEvents |= EV_BPU_REFS;
139*288bf522SAndroid Build Coastguard Worker             }
140*288bf522SAndroid Build Coastguard Worker         }
141*288bf522SAndroid Build Coastguard Worker 
142*288bf522SAndroid Build Coastguard Worker         if (eventMask & EV_BPU_MISSES) {
143*288bf522SAndroid Build Coastguard Worker             pe.type = PERF_TYPE_HARDWARE;
144*288bf522SAndroid Build Coastguard Worker             pe.config = PERF_COUNT_HW_BRANCH_MISSES;
145*288bf522SAndroid Build Coastguard Worker             mCountersFd[BRANCH_MISSES] = perf_event_open(&pe, 0, -1, groupFd, 0);
146*288bf522SAndroid Build Coastguard Worker             if (mCountersFd[BRANCH_MISSES] > 0) {
147*288bf522SAndroid Build Coastguard Worker                 mIds[BRANCH_MISSES] = count++;
148*288bf522SAndroid Build Coastguard Worker                 mEnabledEvents |= EV_BPU_MISSES;
149*288bf522SAndroid Build Coastguard Worker             }
150*288bf522SAndroid Build Coastguard Worker         }
151*288bf522SAndroid Build Coastguard Worker 
152*288bf522SAndroid Build Coastguard Worker #ifdef __ARM_ARCH
153*288bf522SAndroid Build Coastguard Worker         if (eventMask & EV_L1I_REFS) {
154*288bf522SAndroid Build Coastguard Worker             pe.type = PERF_TYPE_RAW;
155*288bf522SAndroid Build Coastguard Worker             pe.config = ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS;
156*288bf522SAndroid Build Coastguard Worker             mCountersFd[ICACHE_REFS] = perf_event_open(&pe, 0, -1, groupFd, 0);
157*288bf522SAndroid Build Coastguard Worker             if (mCountersFd[ICACHE_REFS] > 0) {
158*288bf522SAndroid Build Coastguard Worker                 mIds[ICACHE_REFS] = count++;
159*288bf522SAndroid Build Coastguard Worker                 mEnabledEvents |= EV_L1I_REFS;
160*288bf522SAndroid Build Coastguard Worker             }
161*288bf522SAndroid Build Coastguard Worker         }
162*288bf522SAndroid Build Coastguard Worker 
163*288bf522SAndroid Build Coastguard Worker         if (eventMask & EV_L1I_MISSES) {
164*288bf522SAndroid Build Coastguard Worker             pe.type = PERF_TYPE_RAW;
165*288bf522SAndroid Build Coastguard Worker             pe.config = ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL;
166*288bf522SAndroid Build Coastguard Worker             mCountersFd[ICACHE_MISSES] = perf_event_open(&pe, 0, -1, groupFd, 0);
167*288bf522SAndroid Build Coastguard Worker             if (mCountersFd[ICACHE_MISSES] > 0) {
168*288bf522SAndroid Build Coastguard Worker                 mIds[ICACHE_MISSES] = count++;
169*288bf522SAndroid Build Coastguard Worker                 mEnabledEvents |= EV_L1I_MISSES;
170*288bf522SAndroid Build Coastguard Worker             }
171*288bf522SAndroid Build Coastguard Worker         }
172*288bf522SAndroid Build Coastguard Worker #else
173*288bf522SAndroid Build Coastguard Worker         if (eventMask & EV_L1I_REFS) {
174*288bf522SAndroid Build Coastguard Worker             pe.type = PERF_TYPE_HW_CACHE;
175*288bf522SAndroid Build Coastguard Worker             pe.config = PERF_COUNT_HW_CACHE_L1I |
176*288bf522SAndroid Build Coastguard Worker                 (PERF_COUNT_HW_CACHE_OP_READ<<8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS<<16);
177*288bf522SAndroid Build Coastguard Worker             mCountersFd[ICACHE_REFS] = perf_event_open(&pe, 0, -1, groupFd, 0);
178*288bf522SAndroid Build Coastguard Worker             if (mCountersFd[ICACHE_REFS] > 0) {
179*288bf522SAndroid Build Coastguard Worker                 mIds[ICACHE_REFS] = count++;
180*288bf522SAndroid Build Coastguard Worker                 mEnabledEvents |= EV_L1I_REFS;
181*288bf522SAndroid Build Coastguard Worker             }
182*288bf522SAndroid Build Coastguard Worker         }
183*288bf522SAndroid Build Coastguard Worker 
184*288bf522SAndroid Build Coastguard Worker         if (eventMask & EV_L1I_MISSES) {
185*288bf522SAndroid Build Coastguard Worker             pe.type = PERF_TYPE_HW_CACHE;
186*288bf522SAndroid Build Coastguard Worker             pe.config = PERF_COUNT_HW_CACHE_L1I |
187*288bf522SAndroid Build Coastguard Worker                 (PERF_COUNT_HW_CACHE_OP_READ<<8) | (PERF_COUNT_HW_CACHE_RESULT_MISS<<16);
188*288bf522SAndroid Build Coastguard Worker             mCountersFd[ICACHE_MISSES] = perf_event_open(&pe, 0, -1, groupFd, 0);
189*288bf522SAndroid Build Coastguard Worker             if (mCountersFd[ICACHE_MISSES] > 0) {
190*288bf522SAndroid Build Coastguard Worker                 mIds[ICACHE_MISSES] = count++;
191*288bf522SAndroid Build Coastguard Worker                 mEnabledEvents |= EV_L1I_MISSES;
192*288bf522SAndroid Build Coastguard Worker             }
193*288bf522SAndroid Build Coastguard Worker         }
194*288bf522SAndroid Build Coastguard Worker #endif
195*288bf522SAndroid Build Coastguard Worker     }
196*288bf522SAndroid Build Coastguard Worker #endif // __linux__
197*288bf522SAndroid Build Coastguard Worker     return mEnabledEvents;
198*288bf522SAndroid Build Coastguard Worker }
199*288bf522SAndroid Build Coastguard Worker 
200*288bf522SAndroid Build Coastguard Worker } // namespace utils
201