libkperf is a lightweight performance collection library on linux, that enables developers to perform performance collection in an API fashion. libkperf provides performance data in memory and allows develops to process data directly, reducing overhead of writing and reading perf.data.
v1.3:
v1.2:
v1.1:
v1.0:
Minimum required GCC version:
Minimum required Python version:
To build a library with C API:
git clone --recurse-submodules https://gitee.com/openeuler/libkperf.git
cd libkperf
bash build.sh install_path=/path/to/install
Note:
To build a library with debug version:
bash build.sh install_path=/path/to/install build_type=debug
To build a python package:
bash build.sh install_path=/path/to/install python=true
To uninstall python package:
python3 -m pip uninstall -y libkperf
TO build a Go package:
bash build.sh go=true
After the command is executed successfully, copy go/src/libkperf to GOPATH/src. GOPATH indicates the user project directory.
Refer to docs
directory for detailed docs:
Refer to docs
directory for python API specification docs:
All pmu functions are accomplished by the following interfaces:
Here are some examples:
#include <iostream>
#include "symbol.h"
#include "pmu.h"
#include "pcerrc.h"
int main() {
int pid = getpid();
int pidList[1];
pidList[0] = pid;
char *evtList[1];
evtList[0] = "cycles";
// Initialize event list and pid list in PmuAttr.
// There is one event in list, named 'cycles'.
PmuAttr attr = {0};
attr.evtList = evtList;
attr.numEvt = 1;
attr.pidList = pidList;
attr.numPid = 1;
// Call PmuOpen and pmu descriptor <pd> is return.
// <pd> is an identity for current task.
int pd = PmuOpen(COUNTING, &attr);
// Start collection.
PmuEnable(pd);
// Collect for one second.
sleep(1);
// Stop collection.
PmuDisable(pd);
PmuData *data = NULL;
// Read pmu data. You can also read data before PmuDisable.
int len = PmuRead(pd, &data);
for (int i = 0; i < len; ++i) {
PmuData *d = &data[i];
std::cout << "evt=" << d->evt << "count=" << d->count << std::endl;
}
// To free PmuData, call PmuDataFree.
PmuDataFree(data);
// Like fd, call PmuClose if pd will not be used.
PmuClose(pd);
}
#include <iostream>
#include "symbol.h"
#include "pmu.h"
#include "pcerrc.h"
int main() {
int pid = getpid();
int pidList[1];
pidList[0] = pid;
char *evtList[1];
evtList[0] = "cycles";
// Initialize event list and pid list in PmuAttr.
// There is one event in list, named 'cycles'.
PmuAttr attr = {0};
attr.evtList = evtList;
attr.numEvt = 1;
attr.pidList = pidList;
attr.numPid = 1;
// Call PmuOpen and pmu descriptor <pd> is return.
// <pd> is an identity for current task.
// Use SAMPLING for sample task.
int pd = PmuOpen(SAMPLING, &attr);
// Start collection.
PmuEnable(pd);
// Collect for one second.
sleep(1);
// Stop collection.
PmuDisable(pd);
PmuData *data = NULL;
// Read pmu data. You can also read data before PmuDisable.
int len = PmuRead(pd, &data);
for (int i = 0; i < len; ++i) {
// Get an element from array.
PmuData *d = &data[i];
// Get stack object which is a linked list.
Stack *stack = d->stack;
while (stack) {
// Get symbol object.
if (stack->symbol) {
Symbol *data = stack->symbol;
std::cout << std::hex << data->addr << " " << data->symbolName << "+0x" << data->offset << " "
<< data->codeMapAddr << " (" << data->module << ")"
<< " (" << std::dec << data->fileName << ":" << data->lineNum << ")" << std::endl;
}
stack = stack->next;
}
}
// To free PmuData, call PmuDataFree.
PmuDataFree(data);
// Like fd, call PmuClose if pd will not be used.
PmuClose(pd);
}
import time
from collections import defaultdict
import kperf
def Counting():
evtList = ["r11", "cycles"]
pmu_attr = kperf.PmuAttr(evtList=evtList)
pd = kperf.open(kperf.PmuTaskType.COUNTING, pmu_attr)
if pd == -1:
print(kperf.errorno())
print(kperf.error())
kperf.enable(pd)
for _ in range(3):
time.sleep(1)
data_iter = kperf.read(pd)
evtMap = defaultdict(int)
for data in data_iter.iter:
evtMap[data.evt] += data.count
for evt, count in evtMap.items():
print(f"event: {evt} count: {count}")
kperf.disable(pd)
kperf.close(pd)
import "libkperf/kperf"
import "fmt"
import "time"
func main() {
attr := kperf.PmuAttr{EvtList:[]string{"cycles"}, SymbolMode:kperf.ELF}
fd, err := kperf.PmuOpen(kperf.COUNT, attr)
if err != nil {
fmt.Printf("kperf pmuopen counting failed, expect err is nil, but is %v\n", err)
return
}
kperf.PmuEnable(fd)
time.Sleep(time.Second)
kperf.PmuDisable(fd)
dataVo, err := kperf.PmuRead(fd)
if err != nil {
fmt.Printf("kperf pmuread failed, expect err is nil, but is %v\n", err)
return
}
for _, o := range dataVo.GoData {
fmt.Printf("event: %v count: %v\n", o.Evt, o.Count)
}
kperf.PmuDataFree(dataVo)
kperf.PmuClose(fd)
}
Compilation Command Reference:
g++ -o example example.cpp -I /install_path/include -L /install_path/lib -lkperf -lsym
Run Command Reference:
python example.py
go test -v # run all
go test -v -test.run TestCount #specify the test case to run
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )