libkperf API说明
- 采集类型:
1 2 3 4 5
enum PmuTaskType { COUNTING = 0, // 计数 SAMPLING = 1, // Pmu采样 SPE_SAMPLING = 2, // SPE采样 };
- 指标类型:
1 2 3 4 5 6 7 8
enum PmuMetricType { TMA_LEVEL1, // topdown level1 TMA_FRONTEND, // topdown frontend TMA_BADSPEC, // topdown bad speculation TMA_CORE_BOUND, // topdown core bound TMA_MEM_BOUND, // topdown memory bound TMA_RESOURCE_BOUND, // topdown resource bound };
- 指标聚合类型:
1 2 3 4 5 6 7
enum AggregateType { PER_SYSTEM, // 以系统为维度 PER_CORE, // 以core为维度 PER_NUMA, // 以numa为维度 PER_SOCKET, // 以socket为维度 PER_THREAD, // 以线程为维度 };
- SPE数据选择器:
1 2 3 4 5 6 7 8 9 10 11
enum SpeFilter { SPE_FILTER_NONE = 0, TS_ENABLE = 1UL << 0, // 使用通用计时器的值启用时间戳 PA_ENABLE = 1UL << 1, // 收集load和store的物理地址(以及VA) PCT_ENABLE = 1UL << 2, // 收集物理时间戳而不是虚拟时间戳 JITTER = 1UL << 16, // 使用抖动避免采样时的共振 BRANCH_FILTER = 1UL << 32, // 收集分支 LOAD_FILTER = 1UL << 33, // 收集load指令 STORE_FILTER = 1UL << 34, // 收集store指令 SPE_DATA_ALL = TS_ENABLE | PA_ENABLE | PCT_ENABLE | JITTER | BRANCH_FILTER | LOAD_FILTER | STORE_FILTER };
- SPE事件选择器:
1 2 3 4 5 6 7
enum SpeEventFilter { SPE_EVENT_NONE = 0, SPE_EVENT_RETIRED = 0x2, // instruction retired SPE_EVENT_L1DMISS = 0x8, // L1D refill SPE_EVENT_TLB_WALK = 0x20, // TLB refill SPE_EVENT_MISPREDICTED = 0x80, // mispredict };
- 任务属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
struct PmuAttr { char** evtList; // 事件列表 unsigned numEvt; // 事件列表的长度 int* pidList; // pid列表 unsigned numPid; // pid列表的长度 int* cpuList; // cpu id列表 unsigned numCpu; // cpu id列表的长度 union { unsigned period; // 采样周期 unsigned freq; // 采样频率 }; unsigned useFreq : 1; // 是否使用采样频率,如果为1,那么上一个union表示频率,如果为0,那么上一个union表示周期[L(T1] // SPE related fields. enum SpeFilter dataFilter; // SPE数据选择器 enum SpeEventFilter evFilter; // SPE事件选择器 unsigned long minLatency; // 仅采集具有此延迟或更高延迟的样本 };
- topdown level1数据:
1 2 3 4 5 6 7
struct TmaLevel1 { float ipc; float retired; float backendBd; float frontendBd; float badSpeculation; };
- topdown frontend数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
struct TmaFtEndBd { struct TmaLevel1* level1; float fetchLatencyBound; float itlbMiss; float l1Tlb; float l2Tlb; float icacheMiss; float l1Miss; float l2Miss; float bpMispFlush; float oooFlush; float spFlush; float fetchBandwidthBound; };
- topdown core bound数据:
1 2 3 4 5 6 7
struct TmaCoreBd { struct TmaLevel1* level1; float coreBound; float divider; float fsuStall; float exePortsUtil; };
- topdown bad speculation数据:
1 2 3 4 5 6 7 8 9 10 11
struct TmaBadSpec { struct TmaLevel1* level1; float branchMispredict; float indirectBranch; float pushBranch; float popBranch; float otherBranch; float machineClear; float nukeFlush; float otherFlush; };
- topdown memory bound数据:
1 2 3 4 5 6 7 8
struct TmaMemBd { struct TmaLevel1* level1; float memoryBound; float l1Bound; float l2Bound; float memBound; float storeBound; };
- topdown resource bound数据:
1 2 3 4 5 6 7 8 9 10 11 12
struct TmaResourceBd { struct TmaLevel1* level1; float resourceBound; float syncStall; float robStall; float ptagStall; float saveopqStall; float pcBufferStall; float ccphysicalStall; float intphysicalStall; float vfpphysicalStall; };
- 指标数据:
1 2 3 4 5 6 7 8
union PmuMetricData { struct TmaLevel1* level1; struct TmaFtEndBd* tmaFtEndBd; struct TmaCoreBd* tmaCorebd; struct TmaBadSpec* tmaBadSpec; struct TmaMemBd* tmaMemBd; struct TmaResourceBd* tmaResourceBd; };
- 指标数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
struct PmuMetric { int id; // 根据AggregateType,id有不同的含义: // PER_SYSTEM,id等于-1; // PER_CORE,id表示cpu id; // PER_NUMA,id表示numa id; // PER_SOCKET,id表示socket id; // PER_THREAD,id表示pid。 int metricType; // 聚合类型 union PmuMetricData data; // 指标数据 }; struct PmuDataExt { unsigned long pa; // 物理地址 unsigned long va; // 虚拟地址 unsigned long event; // 事件id }; struct SampleRawData { char *data; // tracepointer事件对应的raw data数据 }; struct SampleRawField { char* fieldName; // 字段名称 char* fieldStr; // 字段描述 unsigned offset; // 偏移量 unsigned size; // 字节数 unsigned isSigned; // 是否有符号 }; struct PmuData { struct Stack* stack; // 调用栈 const char *evt; // 事件名称 int64_t ts; // 时间戳 pid_t pid; // 进程id int tid; // 线程id unsigned cpu; // cpu id struct CpuTopology *cpuTopo; // cpu拓扑 const char *comm; // 进程的命令 uint64_t period; // 采集时长 uint64_t count; // 当前数据的计数。只有在COUNTING类型下才有效 struct PmuDataExt *ext; // 扩展数据,目前只在SPE类型下才有效 struct SampleRawData *rawData; // tracepointer事件对应的raw data数据 };
- 初始化采集任务。
1
int PmuOpen(enum PmuTaskType collectType, struct PmuAttr *attr);
- 执行采集过程。
如果<milliseconds>是-1,则一直会采集到进程结束或者采集被PmuStop停止。
返回值是错误码。
1
int PmuCollect(int pd, int milliseconds);
- 停止采集过程:
1
void PmuStop(int pd);
- 读取上一次的采集数据,数据存放在<pmuData>,<pmuData>是数组结构。
如果读取数据失败,则返回-1。
1
int PmuRead(int pd, struct PmuData** pmuData);
- 关闭<pd>对应的采集任务
1
void PmuClose(int pd);
- 获取topdown的事件列表,用于调用PmuOpen。
1
const char** PmuTopDownEvents(enum PmuMetricType metric, unsigned *numEvt);
- 根据指标类型和聚合类型计算指标数据。
返回值是<metric>的长度。
如果计算指标数据失败,则返回-1。
1 2
int PmuComputeMetric( int pd, enum PmuMetricType metricType, enum AggregateType aggregateType, struct PmuMetric** metric);
- 释放struct PmuMetric*。
1
void PmuMetricFree(struct PmuMetric* metricData);
- 释放struct PmuData*。
1
void PmuDataFree(struct PmuData* pmuData);
- 获取tracepointer指定字段。
1
int PmuGetField(struct SampleRawData *rawData, const char *fieldName, void *value, uint32_t vSize);
- 获取tracepointer指定字段的说明。
1
struct SampleRawField *PmuGetFieldExp(struct SampleRawData *rawData, const char *fieldName);
父主题: 附录