int PmuOpen(enum PmuTaskType collectType, struct PmuAttr *attr);

初始化Pmu事件的采集任务,获取任务的标识符pd

  • enum PmuTaskType

    • COUNTING PMU计数模式
    • SAMPLING PMU采样模式
    • SPE_SAMPLING SPE采样模式
  • struct PmuAttr

    • char** evtList 采集的事件列表,事件列表可以通过perf list查询
    • unsigned numEvt 采集事件的个数
    • int* pidList 采集的进程id列表
    • unsigned numPid 采集进程id的个数
    • int* cpuList 指定的使用cpu核采集列表,默认采集所有逻辑核
    • unsigned numCpu 采集cpu核的个数
    • struct EvtAttr *evtAttr 用于对各事件做单独属性定义的列表
      • groupId 事件分组ID,同组事件需要使用相同数字表示,不同组事件使用不同的数字代表,如果数字为-1,则不参与事件分组
      • period 如果PmuAttr中useFreq=True则为采样频率,否则为采样间隔
      • excludeUser 排除对用户态数据的采集
      • excludeKernel 排除对内核态数据的采集
    • unsigned numEvtAttr 单独定义的事件数
    • union unsigned period 采样周期,仅支持SAMPLING和SPE_SAMPLING模式 unsigned freq 采样频率,仅支持SAMPLING模式
    • unsigned useFreq 是否启用采样频率,如果设置,将可以使用采样频率
    • unsigned excludeUser 排除对用户态数据的采集
    • unsigned excludeKernel 排除对内核态数据的采集
    • enum SymbolMode symbolMode 符号采集模式
      • NO_SYMBOL_RESOLVE = 0 不支持符号采集
      • RESOLVE_ELF = 1 仅支持ELF数据采集,解析function,不解析行号
      • RESOLVE_ELF_DWARF = 2 既支持ELF数据采集,也支持行号解析
    • unsigned callStack 是否采集调用栈,默认不采集,只取栈顶数据
    • unsigned blockedSample 是否执行blocked Sample采样
    • enum SpeFilter dataFilter
      • SPE_FILTER_NONE = 0
      • TS_ENABLE = 1 << 0 使能通用计时器
      • PA_ENABLE = 1 << 1 采集物理地址
      • PCT_ENABLE = 1 << 2 采集物理地址的事件戳替代虚拟地址
      • JITTER = 1 << 16 采样时使用共振防止抖动
      • BRANCH_FILTER = 1 << 32 只采集分支数据
      • LOAD_FILTER = 1 << 33 只采集已加载数据
      • STORE_FILTER = 1 << 34 只采集存储数据
      • SPE_DATA_ALL = TS_ENABLE | PA_ENABLE | PCT_ENABLE | JITTER | BRANCH_FILTER | LOAD_FILTER | STORE_FILTER
    • enum SpeEventFilter evFilter
      • 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
    • unsigned long minLatency 仅收集该latency或者更高的样本数据
    • unsigned includeNewFork 是否支持子线程拆分,仅在COUNTING模式中支持
    • unsigned long branchSampleFilter
      • KPERF_NO_BRANCH_SAMPLE = 0 不采集branch sample stack数据
      • KPERF_SAMPLE_BRANCH_USER = 1 << 0 分支目标位于用户空间
      • KPERF_SAMPLE_BRANCH_KERNEL = 1 << 1 分支目标位于内核空间
      • KPERF_SAMPLE_BRANCH_HV = 1 << 2 分支目标位于虚拟机管理程序中
      • KPERF_SAMPLE_BRANCH_ANY = 1 << 3 任意分支目标
      • KPERF_SAMPLE_BRANCH_ANY_CALL = 1 << 4 任意调用分支(包括直接调用,间接调用和远程调用)
      • KPERF_SAMPLE_BRANCH_ANY_RETURN = 1 << 5 任意返回分支
      • KPERF_SAMPLE_BRANCH_IND_CALL = 1 << 6 间接调用分支
      • KPERF_SAMPLE_BRANCH_ABORT_TX = 1 << 7 事物性内存中止
      • KPERF_SAMPLE_BRANCH_IN_TX = 1 << 8 事物内存分支
      • KPERF_SAMPLE_BRANCH_NO_TX = 1 << 9 分支不在事物性内存事物中
      • KPERF_SAMPLE_BRANCH_COND = 1 << 10 条件分支
      • KPERF_SAMPLE_BRANCH_CALL_STACK = 1 << 11 调用栈分支
      • KPERF_SAMPLE_BRANCH_IND_JUMP = 1 << 12 跳跃分支
      • KPERF_SAMPLE_BRANCH_CALL = 1 << 13 调用分支
      • KPERF_SAMPLE_BRANCH_NO_FLAGES = 1 << 14 无标志
      • KPERF_SAMPLE_BRANCH_NO_CYCLES = 1 << 15 无循环
      • KPERF_SAMPLE_BRANCH_TYPE_SAVE = 1 << 16 存储分支类型 branchSampleFilter对应的比特值,使用方式: attr.branchSampleFilter = KPERF_SAMPLE_BRANCH_USER | KPERF_SAMPLE_BRANCH_ANY; 仅支持SAMPLING模式, 其中KPERF_SAMPLE_BRANCH_USER, KPERF_SAMPLE_BRANCH_KERNEL, KPERF_SAMPLE_BRANCH_HV使用时必须搭配KPERF_SAMPLE_BRANCH_ANY或者KPERF_SAMPLE_BRANCH_ANY之后的值一起使用
    • char** cgroupNameList; 采集cgroup的名称列表
    • unsigned numCgroup; 采集cgroup的个数
    • unsigned enableUserAccess 是否直接读取寄存器,仅支持COUNTING模式
    • unsigned enableBpf 是否基于BPF采集,仅支持COUNTING模式
    • unsigned enableHwMetric 是否使能hWMetric, 该模式需要两个事件指标配对进行采样
    • unsigned enableOnExec 使能enableOnExec,适用于launch模式,在fork之后,未拉起子应用之前PmuOpen,PmuOpen成功之后再去拉起子应用,能规避多线程和短时间应用无数据问题
    • unsigned perThread per thread的模式,每个线程会单独开一个perf_event_open,开启时cpu设置为-1,去监测对应事件,但是该模式不会监测新开子进程的该事件,并且只支持sampling采样
  • 返回值 > 0 初始化成功 返回值 = -1 初始化失败,可通过Perror()查看错误信息

const char** PmuEventList(enum PmuEventType eventType, unsigned *numEvt);

查找所有的事件列表

  • enum PmuEventType:

    • CORE_EVENT 获取core事件列表
    • UNCORE_EVENT 获取uncore事件列表
    • TRACE_EVEN 获取tracepointer事件列表
    • ALL_EVENT 获取所有的事件列表
  • 返回事件列表,可通过for循环遍历该单元

int PmuEnable(int pd);

开启某个pd的采集能力,pd为PmuOpen的返回值

  • 返回值 = 0 使能正常 返回值 = -1 使能异常

int PmuDisable(int pd);

关闭某个pd的采集,pd为PmuOpen的返回值

  • 返回值 = 0 关闭采集正常 返回值 = -1 关闭采集异常

int PmuRead(int pd, struct PmuData** pmuData);

读取pd采样的数据,pd为PmuOpen的返回值

  • struct PmuData

    • struct Stack stack
      • struct Symbol symbol
        • unsigned long addr 地址
        • char* module 模块名称
        • char* symbolName 符号名
        • char* mangleName mangle后的符号名
        • char* fileName 文件名称
        • unsigned int lineNum 行号
        • unsigned long offset 地址偏移
        • unsigned long codeMapEndAddr 结束地址
        • unsigned long codeMapAddr 初始地址
        • unsigned int firstLine 首行
        • mntPoint 挂载点
      • Stack next 下一个stack
      • Stack prev 前一个stack
    • const char *evt: 事件名称
    • int64_t ts: Pmu采集时间戳
    • pid_t pid: 进程ID
    • int tid: 线程ID
    • int cpu: cpuID
    • int groupId: 事件分组的Id
    • struct CpuTopology cpuTopo:
      • int coreId 系统核ID
      • int numaId numaID
      • int socketId socketId
    • const char *comm: 执行指令名称
    • uint64_t period: 采样间隔
    • uint64_t count: 计数
    • double countPercent: 计数比值,使能时间/运行时间
    • struct PmuDataExt ext: SPE特有数据
      • union
        • struct
          • unsigned long pa 物理地址
          • unsigned long va 虚拟地址
          • unsigned long event 事件ID
          • unsigned short lat 调度操作到执行操作的周期数
          • unsigned short source 记录加载或存储操作的数据来源
        • struct
          • unsigned long nr branchRecords的数量
          • struct BranchSampleRecord *branchRecords branch指针数组
    • struct SampleRawData rawData: tracepointer数据指针
    • const char* cgroupName: cgroup名称
  • 返回值 = 0 且 pmuData为空 采集时间内无可用数据 返回值 != 0 且 pmuData为空 采集时发生错误,无法读取数据

void PmuClose(int pd);

清理该pd所有的对应数据,并移除该pd

void PmuDataFree(struct PmuData* pmuData);

清理PmuData

int ResolvePmuDataSymbol(struct PmuData* pmuData);

当SymbolMode设置为3或者4时,可通过该接口解析read返回的PmuData数据中的符号

int PmuDumpData(struct PmuData *pmuData, unsigned len, char *filepath, int dumpDwf);

  • pmuData 由PmuRead返回的PmuData数据
  • len PmuData数据的长度
  • filePath 数据落盘写入路径
  • dump_dwf 是否写入dwarf数据

int PmuTraceOpen(enum PmuTraceType traceType, struct PmuTraceAttr *traceAttr);

  • PmuTraceType traceType
    • TRACE_SYS_CALL 采集系统调用函数事件
  • PmuTraceAttr traceAttr
    • const char **funcs 采集的系统调用函数列表,可以查看/usr/include/asm-generic/unistd.h文件,默认为空,表示采集所有系统调用函数
    • unsigned numFuncs funcs的个数
    • int* pidList 采集的进程id列表
    • unsigned numPid 采集进程id的个数
    • int* cpuList 指定的使用cpu核采集列表,默认采集所有逻辑核
    • unsigned numCpu 采集cpu核的个数
    • CpuList []int采集的cpu列表,默认为空,表示采集所有cpu
  • 返回值 > 0 采集初始化成功 返回值 = -1 采集初始化失败

int PmuTraceEnable(int pd);

该接口用于开启某个pd的采样能力

  • 返回值 = 0 使能正常 返回值 = -1 使能异常

int PmuTraceDisable(int pd);

该接口用于关闭某个pd的采样能力

  • 返回值 = 0 关闭采集正常 返回值 = -1 关闭采集异常

int PmuTraceRead(int pd, struct PmuTraceData** pmuData);

  • taskId int kperf.PmuOpen返回的taskId

  • type PmuTraceDataVo struct

    • GoTraceData []PmuTraceData
  • type PmuTraceData struct

    • FuncName string 系统调用函数名
    • ElapsedTime float64 耗时时间
    • StartTs 开始时间戳
    • Pid int 进程id
    • Tid int 线程id
    • Cpu int cpu号
    • Comm string 执行指令名称

void PmuTraceClose(int pd);

该接口用于清理该pd所有对应的数据,并移除该taskId

const char** PmuSysCallFuncList(unsigned *numFunc);

查找所有的系统调用函数列表

void PmuTraceDataFree(struct PmuTraceData* pmuTraceData);

清理pmuTraceData

int PmuDeviceOpen(struct PmuDeviceAttr *attr, unsigned len);

初始化采集uncore事件指标的能力

  • struct PmuDeviceAttr struct:
    • enum PmuDeviceMetric metric: 指定需要采集的指标
      • PMU_DDR_READ_BW 采集每个channel的ddrc的读带宽,单位:Bytes
      • PMU_DDR_WRITE_BW 采集每个channel的ddrc的写带宽,单位:Bytes
      • PMU_L3_TRAFFIC 采集每个core的L3的访问字节数,单位:Bytes
      • PMU_L3_MISS 采集每个core的L3的miss数量,单位:count
      • PMU_L3_REF 采集每个core的L3的总访问数量,单位:count
      • PMU_L3_LAT 采集每个cluster的L3的总时延,单位:cycles
      • PMU_PCIE_RX_MRD_BW 采集pcie设备的rx方向上的读带宽,单位:Bytes/us
      • PMU_PCIE_RX_MWR_BW 采集pcie设备的rx方向上的写带宽,单位:Bytes/us
      • PMU_PCIE_TX_MRD_BW 采集pcie设备的tx方向上的读带宽,单位:Bytes/us
      • PMU_PCIE_TX_MWR_BW 采集pcie设备的tx方向上的读带宽,单位:Bytes/us
      • PMU_PCIE_RX_MRD_LAT 采集pcie设备的rx方向上的读延时,单位:ns
      • PMU_PCIE_RX_MWR_LAT 采集pcie设备的rx方向上的写延时,单位:ns
      • PMU_PCIE_TX_MRD_LAT 采集pcie设备的tx方向上的读延时,单位:ns
      • PMU_SMMU_TRAN 采集指定smmu设备的地址转换次数,单位:count
      • PMU_HHA_CROSS_NUMA 采集每个numa的跨numa访问HHA的操作比例
      • PMU_HHA_CROSS_SOCKET 采集每个numa的跨socket访问HHA的操作比例
    • char *bdf: 指定需要采集设备的bdf号,只对pcie带宽和smmu指标有效
    • char *port: 指定需要采集设备的port号,只对pcie延时指标有效
  • 与PmuOpen类似,返回task Id 返回值 > 0 初始化成功 返回值 = -1 初始化失败,可通过Perror()查看错误信息

int PmuGetDevMetric(struct PmuData *pmuData, unsigned len,struct PmuDeviceAttr *attr, unsigned attrLen, struct PmuDeviceData **data);

对原始read接口的数据,按照device_attr中给定的指标进行数据聚合,返回值是PmuDeviceData

  • struct ImplPmuDeviceData:
    • enum PmuDeviceMetric metric: 采集的指标
    • double count:指标的计数值
    • enum PmuMetricMode mode: 指标的采集类型,包括 PMU_METRIC_INVALID, PMU_METRIC_CORE, PMU_METRIC_NUMA, PMU_METRIC_CLUSTER, PMU_METRIC_BDF, PMU_METRIC_CHANNEL
    • union:
      • unsigned coreId: 数据的core编号
      • unsigned numaId: 数据的numa编号
      • unsigned clusterId: 簇ID
      • unsigned bdf: 数据的bdf编号
      • unsigned port: 数据的port编号
      • struct: ddr相关的统计数据
        • unsigned channelId: ddr数据的channel编号
        • unsigned ddrNumaId: ddr数据的numa编号
        • unsigned socketId: ddr数据的socket编号

int PmuGetNumaCore(unsigned nodeId, unsigned **coreList);

查询指定numaId下对应的core列表,返回列表长度

int PmuGetClusterCore(unsigned clusterId, unsigned **coreList);

查询指定clusterId下对应的core列表,返回列表长度

const char** PmuDeviceBdfList(enum PmuBdfType bdfType, unsigned *numBdf);

从系统中查找所有的bdf列表

  • enum PmuBdfType
    • PMU_BDF_TYPE_PCIE PCIE设备对应的bdf
    • PMU_BDF_TYPE_SMMU SMMU设备对应的bdf

void DevDataFree(struct PmuDeviceData *data);

清理PmuDeviceData的指针数据

int64_t PmuGetCpuFreq(unsigned core);

查询当前系统指定core的实时CPU频率

  • core: CPU的core编号
  • 返回值:指定core的实时频率,单位: Hz

int PmuOpenCpuFreqSampling(unsigned period);

开启cpu频率采集

struct PmuCpuFreqDetail* PmuReadCpuFreqDetail(unsigned* cpuNum);

读取开启频率采集到读取时间内的cpu最大频率、最小频率以及平均频率

void PmuCloseCpuFreqSampling();

关闭cpu频率采集

PmuFile PmuBeginWrite(const char *path, const struct PmuAttr *pattr, const int addIdHdr);

用于把性能数据输出为perf.data格式的文件。该函数用于初始化该文件。
目前该文件只支持SAMPLING模式,只支持基本信息的输出,比如id, tid, pid, addr,也包含brbe的数据。

  • path: 文件路径
  • pattr: 采集任务的PmuAttr
  • addIdHdr: 为属于非PERF_RECORD_SAMPLE采样的ID
  • 返回值: 文件句柄,用于下面两个API的调用

int PmuWriteData(PmuFile file, struct PmuData *data, int len);

把PmuData数组输出到文件里。

  • file: 文件句柄
  • data: 性能数据
  • len: data的长度
  • 返回值: 错误码

void PmuEndWrite(PmuFile file);

结束文件的写入。在写入结束时必须调用该函数,否则文件可能不完整。

  • file: 文件句柄