/**
* 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.0.zip (1602个子文件)
AUTHORS 42KB
authors 284B
ReactCoffeeScriptClass-test.coffee 16KB
hardware-counter.cpp 12KB
jsc-perf.cpp 5KB
thread-local.cpp 2KB
perf-counters.cpp 1KB
root.css 7KB
style.css 4KB
SettingsShared.css 2KB
codemirror-paraiso-dark.css 2KB
OwnersStack.css 2KB
Profiler.css 2KB
index.css 2KB
TabBar.css 2KB
Element.css 2KB
SelectedElement.css 2KB
hydration.css 1KB
SidebarSelectedFiberInfo.css 1KB
Tree.css 1KB
SidebarCommitInfo.css 1004B
StyleEditor.css 986B
EditableValue.css 977B
DevTools.css 940B
HooksTree.css 927B
style.css 918B
Toggle.css 907B
InteractionListItem.css 895B
InspectedElementTree.css 842B
LayoutViewer.css 826B
SidebarInteractions.css 825B
RecordToggle.css 816B
SettingsModal.css 811B
ModalDialog.css 765B
Components.css 736B
Button.css 697B
SearchInput.css 693B
ChartNode.css 626B
KeyValue.css 611B
ProfilingImportExportButtons.css 522B
SnapshotSelector.css 494B
ErrorBoundary.css 478B
Badge.css 475B
styles.css 460B
AutoSizeInput.css 434B
SnapshotCommitList.css 397B
Chrome.css 394B
HocBadges.css 387B
SnapshotCommitListItem.css 338B
Tooltip.css 326B
styles.css 303B
NoCommitData.css 282B
SelectedTreeHighlight.css 269B
ListItem.css 260B
Page.css 243B
NoInteractions.css 240B
index.css 189B
List.css 189B
EditableName.css 175B
CommitFlamegraph.css 151B
ExpandCollapseToggle.css 135B
WarnIfLegacyBackendDetected.css 127B
ReactLogo.css 120B
Interactions.css 101B
index.css 87B
ButtonIcon.css 69B
Icon.css 63B
CommitRanked.css 60B
RootSelector.css 23B
.editorconfig 293B
.env 30B
.eslintignore 461B
eslintignore 211B
index.cjs.js.flow 34B
index.esm.js.flow 34B
flowconfig 1KB
grayarrow.gif 111B
.gitattributes 12B
.gitignore 778B
.gitignore 587B
.gitignore 395B
.gitignore 345B
.gitignore 285B
.gitignore 175B
.gitignore 52B
.gitignore 23B
.gitignore 23B
.gitignore 19B
.gitignore 10B
.gitignore 10B
.gitignore 9B
.gitignore 9B
.gitignore 9B
.gitignore 9B
.gitignore 9B
.gitignore 9B
.gitignore 9B
.gitignore 9B
.gitignore 9B
binding.gyp 259B
共 1602 条
- 1
- 2
- 3
- 4
- 5
- 6
- 17
资源评论
a3737337
- 粉丝: 0
- 资源: 2869
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- FM9919E:高性能副边同步整流驱动芯片的技术解析
- (源码)基于Spring Security和Redis的单点登录系统.zip
- (源码)基于Arduino实现的CRC硬件校验系统.zip
- 半桥电路的开环仿真PSIM
- (源码)基于C++的RucBase数据库管理系统.zip
- 美国华盛顿州电动汽车保有量数据集(21W+记录)CSV+XML+JSON+RDF格式
- 低功耗原边反馈开关电源芯片TC2526HA/TC2526HB的技术解析
- (源码)基于PyTorch框架的图像识别系统.zip
- Java项目:图书管理系统(基于Java+Springboot+Maven+MyBatisPlus+Vue+Mysql)
- 使用C语言实现字符串逆序输出实现方式.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功