1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/openeuler-libkperf

Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.en.md

libkperf

Описание

libkperf — это легковесная библиотека для сбора производительности на Linux, которая позволяет разработчикам собирать данные о производительности с использованием API. libkperf предоставляет данные о производительности в памяти и позволяет разработчикам обрабатывать данные напрямую, снижая накладные расходы на запись и чтение perf.data.

Когда я могу использовать libkperf?

  • Хочу собирать данные о производительности системы или приложения с минимальными накладными расходами.
  • При анализе производительности тяжелой нагрузки без значительного влияния на производительность.
  • Не хочу управлять несколькими процессами сбора данных и хочу анализировать данные в удобном формате.
  • Хочу собирать горячие точки с минимальными накладными расходами.
  • Хочу анализировать задержку и коэффициент промахов кэша CPU.
  • Хочу отслеживать время выполнения системных вызовов.
  • Хочу собирать пропускную способность контроллера DDR.
  • Хочу собирать пропускную способность и задержку сети.

Поддерживаемые архитектуры CPU

  • Kunpeng

Поддерживаемые ОС

  • openEuler
  • OpenCloudOS
  • TencentOS
  • KylinOS
  • CentOS

Примечания к выпуску

v1.3:

  • Поддержка сбора времени выполнения системных вызовов.
  • Поддержка выборки записей ветвления.

v1.2:

  • Поддержка точек трассировки.
  • Поддержка групповой сборки событий.

v1.1:

  • Поддержка API Python.

v1.0:

  • Поддержка подсчета производительности, выборки и выборки SPE.
  • Поддержка событий ядра и неядерных событий.
  • Поддержка анализа символов.

Сборка

Минимальная требуемая версия GCC:

  • gcc-4.8.5 и glibc-2.17.

Минимальная требуемая версия Python:

  • python-3.6.

Для сборки библиотеки с C API:

git clone --recurse-submodules https://gitee.com/openeuler/libkperf.git
cd libkperf
bash build.sh install_path=/path/to/install

Примечание:

  • Если сообщение об ошибке компиляции указывает на отсутствие файла numa.h, вам нужно сначала установить соответствующий пакет numactl-devel.
  • Если вы сталкиваетесь с ошибкой CMake, связанной с 'Found PythonInterp' во время компиляции икомпоновки, вам нужно сначала установить необходимый пакет python3-devel.

Для сборки библиотеки с отладочной версией:

bash build.sh install_path=/path/to/install build_type=debug

Для сборки пакета Python:

bash build.sh install_path=/path/to/install python=true

Для удаления пакета Python:

python3 -m pip uninstall -y libkperf

Для сборки пакета Go:

bash build.sh go=true

После успешного выполнения команды скопируйте go/src/libkperf в GOPATH/src. GOPATH указывает на директорию проекта пользователя.

Документация

См. каталог docs для подробной документации:

См. каталог docs для спецификации API Python:

Инструкции

Все функции PMU выполняются следующими интерфейсами:

  • PmuOpen Ввод PID, ID ядра и события и открытие устройства PMU.
  • PmuEnable Начало сбора данных.
  • PmuRead Чтение данных сбора.
  • PmuDisable Остановка сбора данных.
  • PmuClose Закрытие устройства PMU.

Вот несколько примеров:

  • Получение количества PMU для процесса
#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";
    // Инициализация списка событий и списка PID в PmuAttr.
    // В списке одно событие, называемое 'cycles'.
    PmuAttr attr = {0};
    attr.evtList = evtList;
    attr.numEvt = 1;
    attr.pidList = pidList;
    attr.numPid = 1;
    // Вызов PmuOpen и возвращение дескриптора PMU <pd>.
    // <pd> является идентификатором текущей задачи.
    int pd = PmuOpen(COUNTING, &attr);
    // Начало сбора данных.
    PmuEnable(pd);
    // Сбор данных в течение одной секунды.
    sleep(1);
    // Остановка сбора данных.
    PmuDisable(pd);
    PmuData *data = NULL;
    // Чтение данных PMU. Вы также можете читать данные до 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;
    }
    // Для освобождения PmuData вызовите PmuDataFree.
    PmuDataFree(data);
    // Как и для fd, вызовите PmuClose, если pd больше не будет использоваться.
    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";
    // Инициализация списка событий и списка PID в PmuAttr.
    // В списке одно событие, называемое 'cycles'.
    PmuAttr attr = {0};
    attr.evtList = evtList;
    attr.numEvt = 1;
    attr.pidList = pidList;
    attr.numPid = 1;
    // Вызов PmuOpen и возвращение дескриптора PMU <pd>.
    // <pd> является идентификатором текущей задачи.
    // Используйте SAMPLING для выборки задачи.
    int pd = PmuOpen(SAMPLING, &attr);
    // Начало сбора данных.
    PmuEnable(pd);
    // Сбор данных в течение одной секунды.
    sleep(1);
    // Остановка сбора данных.
    PmuDisable(pd);
    PmuData *data = NULL;
    // Чтение данных PMU. Вы также можете читать данные до PmuDisable.
    int len = PmuRead(pd, &data);
    for (int i = 0; i < len; ++i) {
        // Получение элемента из массива.
      PmuData *d = &data[i];
        // Получение объекта стека, который является связанным списком.
        Stack *stack = d->stack;
        while (stack) {
            // Получение объекта символа.
            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;
        }
    }
    // Для освобождения PmuData вызовите PmuDataFree.
    PmuDataFree(data);
    // Как и для fd, вызовите PmuClose, если pd больше не будет использоваться.
    PmuClose(pd);
}
  • Примеры на Python
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)
  • Пример на Go
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)
}

Быстрое руководство по запуску примеров кода:

  • Для примера кода на C++: Вы можете поместить пример кода в функцию main файла исходного кода C++, и включить заголовочные файлы, связанные с этой динамической библиотекой (#include "symbol.h", #include "pmu.h", #include "pcerrc.h"). Затем используйте g++ для компиляции и компоновки этой динамической библиотеки для создания исполняемого файла, который можно запустить.

Команда компиляции:

g++ -o example example.cpp -I /install_path/include -L /install_path/lib -lkperf -lsym
  • Для примера кода на Python: Вы можете поместить пример кода в функцию main файла исходного кода Python, и импортировать пакеты, связанные с этой динамической библиотекой (import kperf, import ksym). Запуск файла Python будет использовать функциональность, предоставляемую этими пакетами.

Команда запуска:

python example.py
  • Для примера кода на Go: Вы можете перейти напрямую в каталог go/src/libkperf_test.
export GO111MODULE=off
export LD_LIBRARY_PATH=../libkperf/lib:$LD_LIBRARY_PATH
go test -v # запуск всех тестов
go test -v -test.run TestCount # запуск конкретного тестового случая
  • Статическая компиляция языка Go:
go build -tags="static"

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Реализуйте библиотеку для низкозатратного сбора данных PMU, предоставляющую абстрактные интерфейсы для подсчета, отбора образцов и разрешения символов. Развернуть Свернуть
MulanPSL-2.0
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/openeuler-libkperf.git
git@api.gitlife.ru:oschina-mirror/openeuler-libkperf.git
oschina-mirror
openeuler-libkperf
openeuler-libkperf
master