/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "hardware-counter.h"
#ifndef NO_HARDWARE_COUNTERS
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm/unistd.h>
#include <sys/prctl.h>
#include <linux/perf_event.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
IMPLEMENT_THREAD_LOCAL_NO_CHECK(HardwareCounter,
HardwareCounter::s_counter);
static bool s_recordSubprocessTimes = false;
static bool s_profileHWEnable;
static std::string s_profileHWEvents;
static inline bool useCounters() {
#ifdef VALGRIND
return false;
#else
return s_profileHWEnable;
#endif
}
class HardwareCounterImpl {
public:
HardwareCounterImpl(int type, unsigned long config,
const char* desc = nullptr)
: m_desc(desc ? desc : ""), m_err(0), m_fd(-1), inited(false) {
memset (&pe, 0, sizeof (struct perf_event_attr));
pe.type = type;
pe.size = sizeof (struct perf_event_attr);
pe.config = config;
pe.inherit = s_recordSubprocessTimes;
pe.disabled = 1;
pe.pinned = 0;
pe.exclude_kernel = 0;
pe.exclude_hv = 1;
pe.read_format =
PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING;
}
~HardwareCounterImpl() {
close();
}
void init_if_not() {
/*
* perf_event_open(struct perf_event_attr *hw_event_uptr, pid_t pid,
* int cpu, int group_fd, unsigned long flags)
*/
if (inited) return;
inited = true;
m_fd = syscall(__NR_perf_event_open, &pe, 0, -1, -1, 0);
if (m_fd < 0) {
// Logger::Verbose("perf_event_open failed with: %s",
// folly::errnoStr(errno).c_str());
m_err = -1;
return;
}
if (ioctl(m_fd, PERF_EVENT_IOC_ENABLE, 0) < 0) {
// Logger::Warning("perf_event failed to enable: %s",
// folly::errnoStr(errno).c_str());
close();
m_err = -1;
return;
}
reset();
}
int64_t read() {
uint64_t values[3];
if (readRaw(values)) {
if (!values[2]) return 0;
int64_t value = (double)values[0] * values[1] / values[2];
return value + extra;
}
return 0;
}
void incCount(int64_t amount) {
extra += amount;
}
bool readRaw(uint64_t* values) {
if (m_err || !useCounters()) return false;
init_if_not();
if (m_fd > 0) {
/*
* read the count + scaling values
*
* It is not necessary to stop an event to read its value
*/
auto ret = ::read(m_fd, values, sizeof(*values) * 3);
if (ret == sizeof(*values) * 3) {
values[0] -= reset_values[0];
values[1] -= reset_values[1];
values[2] -= reset_values[2];
return true;
}
}
return false;
}
void reset() {
if (m_err || !useCounters()) return;
init_if_not();
extra = 0;
if (m_fd > 0) {
if (ioctl (m_fd, PERF_EVENT_IOC_RESET, 0) < 0) {
// Logger::Warning("perf_event failed to reset with: %s",
// folly::errnoStr(errno).c_str());
m_err = -1;
return;
}
auto ret = ::read(m_fd, reset_values, sizeof(reset_values));
if (ret != sizeof(reset_values)) {
// Logger::Warning("perf_event failed to reset with: %s",
// folly::errnoStr(errno).c_str());
m_err = -1;
return;
}
}
}
public:
std::string m_desc;
int m_err;
private:
int m_fd;
struct perf_event_attr pe;
bool inited;
uint64_t reset_values[3];
uint64_t extra{0};
void close() {
if (m_fd > 0) {
::close(m_fd);
m_fd = -1;
}
}
};
class InstructionCounter : public HardwareCounterImpl {
public:
InstructionCounter() :
HardwareCounterImpl(PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS) {}
};
class LoadCounter : public HardwareCounterImpl {
public:
LoadCounter() :
HardwareCounterImpl(PERF_TYPE_HW_CACHE,
(PERF_COUNT_HW_CACHE_L1D | ((PERF_COUNT_HW_CACHE_OP_READ) << 8))) {}
};
class StoreCounter : public HardwareCounterImpl {
public:
StoreCounter() :
HardwareCounterImpl(PERF_TYPE_HW_CACHE,
PERF_COUNT_HW_CACHE_L1D | ((PERF_COUNT_HW_CACHE_OP_WRITE) << 8)) {}
};
HardwareCounter::HardwareCounter()
: m_countersSet(false) {
m_instructionCounter.reset(new InstructionCounter());
if (s_profileHWEvents.empty()) {
m_loadCounter.reset(new LoadCounter());
m_storeCounter.reset(new StoreCounter());
} else {
m_countersSet = true;
setPerfEvents(s_profileHWEvents);
}
}
HardwareCounter::~HardwareCounter() {
}
void HardwareCounter::Init(bool enable, const std::string& events,
bool subProc) {
s_profileHWEnable = enable;
s_profileHWEvents = events;
s_recordSubprocessTimes = subProc;
}
void HardwareCounter::Reset() {
s_counter->reset();
}
void HardwareCounter::reset() {
m_instructionCounter->reset();
if (!m_countersSet) {
m_storeCounter->reset();
m_loadCounter->reset();
}
for (unsigned i = 0; i < m_counters.size(); i++) {
m_counters[i]->reset();
}
}
int64_t HardwareCounter::GetInstructionCount() {
return s_counter->getInstructionCount();
}
int64_t HardwareCounter::getInstructionCount() {
return m_instructionCounter->read();
}
int64_t HardwareCounter::GetLoadCount() {
return s_counter->getLoadCount();
}
int64_t HardwareCounter::getLoadCount() {
return m_loadCounter->read();
}
int64_t HardwareCounter::GetStoreCount() {
return s_counter->getStoreCount();
}
int64_t HardwareCounter::getStoreCount() {
return m_storeCounter->read();
}
void HardwareCounter::IncInstructionCount(int64_t amount) {
s_counter->m_instructionCounter->incCount(amount);
}
void HardwareCounter::IncLoadCount(int64_t amount) {
if (!s_counter->m_countersSet) {
s_counter->m_loadCounter->incCount(amount);
}
}
void HardwareCounter::IncStoreCount(int64_t amount) {
if (!s_counter->m_countersSet) {
s_counter->m_storeCounter->incCount(amount);
}
}
struct PerfTable perfTable[] = {
/* PERF_TYPE_HARDWARE events */
#define PC(n) PERF_TYPE_HARDWARE, PERF_COUNT_HW_ ## n
{ "cpu-cycles", PC(CPU_CYCLES) },
{ "cycles", PC(CPU_CYCLES) },
{ "instructions", PC(INSTRUCTIONS) },
{ "cache-references", PC(CACHE_REFERENCES) },
{ "cache-misses", PC(CACHE_MISSES) },
{ "branch-instructions", PC(BRANCH_INSTRUCTIONS) },
{ "branches", PC(BRANCH_INSTRUCTIONS) },
{ "branch-misses", PC(BRANCH_MISSES) },
{ "bus-cycles", PC(BUS_CYCLES) },
{ "stalled-cycles-frontend", PC(STALLED_CYCLES_FRONTEND) },
{ "stalled-cycles-backend", PC(STALLED_CYCLES_BACKEND) },
/* PERF_TYPE_HW_CACHE hw_cache_id */
#define PCC(n) PERF_TYPE_HW_CACHE, PERF_COUNT_HW_CACHE_ ## n
{ "L1-dcache-", PCC(L1D) },
{ "L1-icache-", PCC(L1I) },
{ "LLC-", PCC(LL) },
{ "dTLB-", PCC(DTLB) },
{ "iTLB-", PCC(ITLB) },
{ "branch-", PCC(BPU) },
/* PERF_TYPE_HW_CACHE hw_cache_op, hw_cache_result */
#define PCCO(n, m) PERF_TYPE_HW_CACHE, \
((PERF_COUNT_HW_CACHE_OP_ ## n) << 8 | \
(PERF_COUNT_HW_CACHE_RESULT_ ## m) << 16)
{ "loads", PCCO(READ, ACCESS) },
{ "load-misses", PCCO(READ, MISS) },
{ "stores", PCCO(WRITE, ACCESS) },
{ "store-misses", PCCO(WRITE, MISS) },
{ "prefetches", PCCO(P
react-16.10.1.tar.gz
需积分: 0 120 浏览量
更新于2024-05-04
收藏 4.24MB GZ 举报
react.js for linux 各个版本,免费下载
前端三大框架之一 react 各个版本,免费下载
如果下载不了,关注我,评论区联系我
React 是一个库。它允许你将组件放在一起,但不关注路由和数据获取。要使用 React 构建整个应用程序,建议使用像 Next.js 或 Remix 这样的全栈 React 框架。
段子手-168
- 粉丝: 4843
- 资源: 2745
最新资源
- 基于MPC的永磁同步电机非线性终端滑模控制仿真研究 matlab simulink 无参考文件
- 本科生课程设计封面.doc
- 基于动物群体行为优化的多椭圆检测算法及其在图像处理的应用
- 适用方向:基于LQR控制算法的直接横摆力矩控制(DYC)的四轮独立电驱动汽车的横向稳定性控制研究 主要内容:利用carsim建模,在simulink中搭建控制器,然后进行联合 实现汽车在高速低附着路
- 永磁同步电机模型预测电流控制Simulink仿真,单矢量控制,带一份报告介绍
- Sim-EKB-Install-2024-12-08
- 跟网型逆变器小干扰稳定性分析与控制策略优化simulink仿真模型和代码 现代逆变技术 阻抗重塑 双锁相环 可附赠参考文献(英文) 和一份与模型完全对应的中文版报告
- 冲压废料收集装置sw18可编辑全套技术资料100%好用.zip
- 【西门子1500吉利(柯马)汽车SICAR项目程序源码】西门子PLC&HMI整套设计资料(源码+注释) 西门子1500 PLC, TP1200触摸屏HMI 非常标准的汽车行业程序(SICAR),修改套
- C++ 基于opencv 4.5 仿halcon 基于形状的模板匹配 ,支持目标缩放以及旋转,支持亚像素精度,源码,支持C#
- 深度学习技术中混沌时间序列预测-基于LSTM、Transformer与CNN的多专家混合模型应用-含详细代码及解释
- 双馈风机惯性控制+下垂控制参与系统一次调频的Matlab Simulink模型,调频结束后转速回复,造成频率二次跌落 系统为三机九节点模型,所有参数已调好且可调,可直接运行,风电渗透率19.4% 风机
- iOS 7.0 ~ 16.7 DeviceSupport.zip
- 软件工程期末复习总结.xmind
- Kriging代理模型 克里金模型 回归预测 根据样本数据建立代理模型,进行预测 Matlab编程
- 高速永磁同步电机的电磁设计 高速永磁电机的体积远小于同等功率的中低速电机,且功率密度高,近年来得到了广泛的发展,在离心压缩机、新能源汽车、航空航天、医疗器械等领域备受青睐 但高速永磁电机的研究主要集