161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian/* 261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian * Copyright (C) 2016 The Android Open Source Project 361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian * 461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian * you may not use this file except in compliance with the License. 661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian * You may obtain a copy of the License at 761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian * 861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian * 1061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian * Unless required by applicable law or agreed to in writing, software 1161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 1261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian * See the License for the specific language governing permissions and 1461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian * limitations under the License. 1561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian */ 1661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 1761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#include "Profiler.h" 1861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 1961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#include <stdlib.h> 2061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#include <string.h> 2161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#include <unistd.h> 2261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 2361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#include <algorithm> 2461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#include <iostream> 2561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 2661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#if defined(__linux__) 2761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 2861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#include <sys/syscall.h> 2961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 3061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#ifdef __ARM_ARCH 3161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian enum ARMv8PmuPerfTypes{ 3261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian // Common micro-architecture events 3361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL = 0x01, 3461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS = 0x14, 3561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS = 0x16, 3661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL = 0x17, 3761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian ARMV8_PMUV3_PERFCTR_L2_CACHE_WB = 0x18, 3861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian }; 3961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#endif 4061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 4161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopianstatic int perf_event_open(struct perf_event_attr* hw_event, pid_t pid, 4261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian int cpu, int group_fd, unsigned long flags) { 4361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian return syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags); 4461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian} 4561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 4661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#endif // __linux__ 4761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 4861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopiannamespace utils { 4961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 5061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias AgopianProfiler& Profiler::get() noexcept { 5161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian static Profiler sProfiler; 5261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian return sProfiler; 5361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian} 5461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 5561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias AgopianProfiler::Profiler() noexcept { 5661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian std::uninitialized_fill(mCountersFd.begin(), mCountersFd.end(), -1); 5761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian Profiler::resetEvents(EV_CPU_CYCLES | EV_L1D_RATES | EV_BPU_RATES); 5861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian} 5961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 6061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias AgopianProfiler::~Profiler() noexcept { 6161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian for (int fd : mCountersFd) { 6261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (fd >= 0) { 6361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian close(fd); 6461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 6561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 6661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian} 6761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 6861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopianuint32_t Profiler::resetEvents(uint32_t eventMask) noexcept { 6961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian // close all counters 7061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian for (int& fd : mCountersFd) { 7161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (fd >= 0) { 7261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian close(fd); 7361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian fd = -1; 7461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 7561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 7661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mEnabledEvents = 0; 7761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 7861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#if defined(__linux__) 7961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 8061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian struct perf_event_attr pe; 8161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian memset(&pe, 0, sizeof(struct perf_event_attr)); 8261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.type = PERF_TYPE_HARDWARE; 8361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.size = sizeof(struct perf_event_attr); 8461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.config = PERF_COUNT_HW_INSTRUCTIONS; 8561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.disabled = 1; 8661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.exclude_kernel = 1; 8761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.exclude_hv = 1; 8861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.read_format = PERF_FORMAT_GROUP | 8961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian PERF_FORMAT_ID | 9061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian PERF_FORMAT_TOTAL_TIME_ENABLED | 9161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian PERF_FORMAT_TOTAL_TIME_RUNNING; 9261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 9361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian uint8_t count = 0; 9461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian int fd = perf_event_open(&pe, 0, -1, -1, 0); 9561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (fd >= 0) { 9661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian const int groupFd = fd; 9761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mIds[INSTRUCTIONS] = count++; 9861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mCountersFd[INSTRUCTIONS] = fd; 9961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 10061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID; 10161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 10261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (eventMask & EV_CPU_CYCLES) { 10361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.type = PERF_TYPE_HARDWARE; 10461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.config = PERF_COUNT_HW_CPU_CYCLES; 10561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mCountersFd[CPU_CYCLES] = perf_event_open(&pe, 0, -1, groupFd, 0); 10661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (mCountersFd[CPU_CYCLES] > 0) { 10761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mIds[CPU_CYCLES] = count++; 10861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mEnabledEvents |= EV_CPU_CYCLES; 10961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 11061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 11161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 11261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (eventMask & EV_L1D_REFS) { 11361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.type = PERF_TYPE_HARDWARE; 11461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.config = PERF_COUNT_HW_CACHE_REFERENCES; 11561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mCountersFd[DCACHE_REFS] = perf_event_open(&pe, 0, -1, groupFd, 0); 11661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (mCountersFd[DCACHE_REFS] > 0) { 11761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mIds[DCACHE_REFS] = count++; 11861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mEnabledEvents |= EV_L1D_REFS; 11961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 12061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 12161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 12261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (eventMask & EV_L1D_MISSES) { 12361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.type = PERF_TYPE_HARDWARE; 12461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.config = PERF_COUNT_HW_CACHE_MISSES; 12561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mCountersFd[DCACHE_MISSES] = perf_event_open(&pe, 0, -1, groupFd, 0); 12661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (mCountersFd[DCACHE_MISSES] > 0) { 12761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mIds[DCACHE_MISSES] = count++; 12861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mEnabledEvents |= EV_L1D_MISSES; 12961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 13061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 13161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 13261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (eventMask & EV_BPU_REFS) { 13361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.type = PERF_TYPE_HARDWARE; 13461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS; 13561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mCountersFd[BRANCHES] = perf_event_open(&pe, 0, -1, groupFd, 0); 13661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (mCountersFd[BRANCHES] > 0) { 13761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mIds[BRANCHES] = count++; 13861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mEnabledEvents |= EV_BPU_REFS; 13961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 14061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 14161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 14261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (eventMask & EV_BPU_MISSES) { 14361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.type = PERF_TYPE_HARDWARE; 14461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.config = PERF_COUNT_HW_BRANCH_MISSES; 14561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mCountersFd[BRANCH_MISSES] = perf_event_open(&pe, 0, -1, groupFd, 0); 14661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (mCountersFd[BRANCH_MISSES] > 0) { 14761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mIds[BRANCH_MISSES] = count++; 14861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mEnabledEvents |= EV_BPU_MISSES; 14961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 15061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 15161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 15261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#ifdef __ARM_ARCH 15361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (eventMask & EV_L1I_REFS) { 15461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.type = PERF_TYPE_RAW; 15561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.config = ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS; 15661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mCountersFd[ICACHE_REFS] = perf_event_open(&pe, 0, -1, groupFd, 0); 15761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (mCountersFd[ICACHE_REFS] > 0) { 15861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mIds[ICACHE_REFS] = count++; 15961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mEnabledEvents |= EV_L1I_REFS; 16061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 16161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 16261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 16361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (eventMask & EV_L1I_MISSES) { 16461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.type = PERF_TYPE_RAW; 16561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.config = ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL; 16661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mCountersFd[ICACHE_MISSES] = perf_event_open(&pe, 0, -1, groupFd, 0); 16761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (mCountersFd[ICACHE_MISSES] > 0) { 16861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mIds[ICACHE_MISSES] = count++; 16961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mEnabledEvents |= EV_L1I_MISSES; 17061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 17161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 17261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#else 17361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (eventMask & EV_L1I_REFS) { 17461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.type = PERF_TYPE_HW_CACHE; 17561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.config = PERF_COUNT_HW_CACHE_L1I | 17661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian (PERF_COUNT_HW_CACHE_OP_READ<<8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS<<16); 17761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mCountersFd[ICACHE_REFS] = perf_event_open(&pe, 0, -1, groupFd, 0); 17861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (mCountersFd[ICACHE_REFS] > 0) { 17961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mIds[ICACHE_REFS] = count++; 18061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mEnabledEvents |= EV_L1I_REFS; 18161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 18261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 18361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 18461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (eventMask & EV_L1I_MISSES) { 18561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.type = PERF_TYPE_HW_CACHE; 18661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian pe.config = PERF_COUNT_HW_CACHE_L1I | 18761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian (PERF_COUNT_HW_CACHE_OP_READ<<8) | (PERF_COUNT_HW_CACHE_RESULT_MISS<<16); 18861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mCountersFd[ICACHE_MISSES] = perf_event_open(&pe, 0, -1, groupFd, 0); 18961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian if (mCountersFd[ICACHE_MISSES] > 0) { 19061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mIds[ICACHE_MISSES] = count++; 19161fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian mEnabledEvents |= EV_L1I_MISSES; 19261fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 19361fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 19461fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#endif 19561fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian } 19661fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian#endif // __linux__ 19761fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian return mEnabledEvents; 19861fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian} 19961fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian 20061fd2ab615ab17f6de593e8a8cf475465967ac9cMathias Agopian} // namespace utils 201