Используйте трассировку для получения информации о производительности системы

Используйте трассировку для записи событий и счетчиков в системе и для визуализации каждого из них на временной шкале. Стандартный инструмент трассировки в Android — Perfetto . Для получения дополнительной информации см. раздел «Трассировка 101» .

Инструментируйте свой код

Для получения событий из приложения необходимо добавить точки трассировки в код. Неинструментированные участки не будут отображаться в трассировках.

Пример трассировки SDV — это демонстрация интеграции трассировки, включающая инструкции и пример конфигурации трассировки. Он находится в system/software_defined_vehicle/core_services/samples/tracing/ .

Ржавчина

Рекомендуемый подход для Rust — использование крейта трассировки для генерации событий ATrace . Perfetto поддерживает ATrace в качестве источника данных. Мы планируем перейти на SDK Perfetto, когда станут доступны привязки для Rust и в зависимости от того, как будут развиваться сценарии использования.

Добавьте параметры трассировки по умолчанию в Android.bp :

rust_binary {
...
    defaults: [
        ...
        "sdv_tracing@rust_defaults",
    ],
...
}

Инициализируйте подписчика. Это можно сделать только один раз для каждого процесса:

fn main() {
    // Initialize the subscriber, panic if it fails.
    // sdv_tracing::try_init_tracing() is the version that returns a Result.
    sdv_tracing::init_tracing()
    ...
}

Вы можете опустить вызов инициализации. В этом случае трассировка останется неинициализированной, и Perfetto не будет собирать события инструментирования из приложения.

Добавьте точки трассировки. Дополнительные примеры можно найти в файле system/software_defined_vehicle/core_services/samples/tracing/rust_tracing_api_demo/tracing.rs .

use tracing::{instrument, info_span};

// #[tracing::instrument] wraps the method into a tracing span and records arguments.
// Use #[instrument(skip(num))] if you don't want to record the argument.
#[instrument]
fn mul_by_100(num: i32) -> i32 {
    // Create and enter a span with INFO verbosity, name, and a debug field annotation.
    // The span will exit when dropped.
    let _span = info_span!("This is a span", var=123).entered();
    let result = num * 100;
    // Emit an instant INFO event that records the result value.
    // We recommend to fully qualify the crate when using events to avoid confusion with log records.
    tracing::info!(result, "Completed");
    result
}

C++

Трассировка C++ использует Perfetto SDK для отслеживания событий . Добавьте параметры трассировки по умолчанию в файл Android.bp :

cc_binary {
...
    defaults: [
...
        "sdv_tracing@cc_defaults",
    ],
...
}

Определите категории. Если вы используете категории в нескольких модулях, переместите их в общую библиотеку. Например, system/software_defined_vehicle/core_services/samples/tracing/cpp_service/tracing_categories.h .

В заголовке:

#include "perfetto/tracing/tracing.h"
#include "perfetto/tracing/track_event.h"

PERFETTO_DEFINE_CATEGORIES(
        perfetto::Category("sample")
                .SetTags("tag")
                .SetDescription("Sample events"));

Разместите макрос статического хранилища в исходном файле .cpp а не в методе. Если вы используете общие категории для разных компонентов, используйте исходный файл, соответствующий заголовочному файлу с категориями.

PERFETTO_TRACK_EVENT_STATIC_STORAGE();

int main() {
    ...
}

Для инициализации Perfetto необходимо инициализировать системный бэкэнд и зарегистрировать события трека:


#include <sdv/tracing_init.h>

int main() {
  ...
  android::sdv::InitPerfettoWithTrackEvents<perfetto::TrackEvent>();
  ...
}

Добавьте средства мониторинга. Дополнительные примеры см. в system/software_defined_vehicle/core_services/samples/tracing/cpp_service/client.cpp .

int32_t mulBy100(int32_t num) {
    // Start a slice that will get closed at the end of the scope.
    TRACE_EVENT("client", "mulBy100", "num", num);

    TRACE_EVENT("client", "This is a slice", "var", 123);
    int32_t result = num * 100;

    // Instant events have zero duration. They are drawn as markers on the track.
    TRACE_EVENT_INSTANT("client", "Completed", "result", result);
    return result;
}

Как и в примере на Rust, этот код создает два вложенных среза и маркер для мгновенного события в пользовательском интерфейсе. Значения аргументов отладки отображаются при выборе события.

Собрать следы

Для записи трассировки используйте скрипт командной строки record\_android\_trace , а для ее просмотра — веб-интерфейс Perfetto .

Настройте захват

Для функции record_android_trace необходимо предоставить конфигурацию в формате textproto. Подробнее см. в документации Perfetto .

В репозитории SDV содержится пример конфигурации ( system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx ). Этот файл включает несколько источников данных и может быть настроен или использован как есть.

Используйте Perfetto UI для создания конфигурации

Вы можете настроить пользовательскую конфигурацию и изучить доступные параметры, перейдя в раздел «Запись новой трассировки» в пользовательском интерфейсе Perfetto, настроив параметры записи и зонды. Затем вы можете открыть окно «Команда записи», чтобы увидеть сгенерированную команду и получить содержимое конфигурации оттуда.

Настройте видимость инструментов мониторинга в приложении.

Инструментарий Rust использует ATrace . Он настраивается в разделе ftrace_config документации. Компоненты SDV имеют тег ATRACE_TAG_APP и могут быть включены для каждого приложения отдельно. Пример конфигурации включает все приложения.

data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            # Setting atrace_apps to "*" enable ATrace events for all apps.
            # You can set it to a pattern to match specific processes by name.
            # Use multiple atrace_apps entries to enable multiple processes.
            atrace_apps: "*"
        }
    }
}

В SDK Perfetto для C++ мы используем события отслеживания. Это источник данных track_event ( документация ).

В поле track_event_config можно включать или отключать категории и теги. По умолчанию включены все закрывающие теги категорий, за исключением специальных тегов slow и debug . Если вы хотите включить только определенные категории, необходимо отключить все остальные, например, с помощью disabled_categories: "*" как здесь:

data_sources: {
    config {
        name: "track_event"
        track_event_config {
            enabled_categories: "the_best_category_in_the_world"
            disabled_categories: "*"
        }
    }
}

Записать трассировку

Откройте терминал в корневом каталоге репозитория Android. Выполнять envsetup не требуется. Скрипт записи находится в external/perfetto/tools/record_android_trace .

Запустите скрипт с примером конфигурации:

external/perfetto/tools/record_android_trace --config system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx

Чтобы остановить запись раньше времени, нажмите Ctrl + C.

В этом случае adb shell perfetto запишет трассировку, а затем передаст её на хост, обычно в ~/traces . После сбора трассировки инструмент откроет окно браузера для её отображения.

Полезные аргументы:

  • -s SERIAL — использовать устройство с указанным последовательным портом. Например -s 0.0.0.0:6520

  • --no-open-browser создаст URL-адрес для отображения трассировки, но не откроет браузер. Он полезен для удалённых сессий, когда настроена переадресация портов (обычно 9001).

  • -n, --no-open не откроет браузер и не позволит использовать URL-адрес для отображения трассировки после завершения сеанса трассировки. Вы по-прежнему можете открывать файлы в пользовательском интерфейсе Perfetto, нажав на кнопку «Открыть файл трассировки» и выбрав нужный файл.

  • -o <path> для установки пути вывода.

Подробности использования

В этом разделе представлена ​​информация, которая может быть полезна при использовании системы отслеживания.

Контрольно-измерительные приборы в компонентах SDV

В агентах с инструментами трассировки трассировка доступна по умолчанию для отладочных сборок ( -eng , -userdebug ), если не указано иное. При сборе трассировки вы должны увидеть события для процессов без дополнительной настройки.

Библиотеки обычно не инициализируют трассировку автоматически. В Rust исполняемый файл, использующий библиотеку, должен инициализировать трассировку для процесса с помощью sdv_tracing::init_tracing() . Подробнее см. в разделе «Инструментирование кода» .

Промежуточное программное обеспечение

Библиотека для публикации/подписки : libsdv_middleware_dt

События:

  • Издатель: Публикация и регистрация тем.
  • Подписчик: Подписка и участие в опросах.

Включение: вызовите функцию sdv_tracing::init_tracing() или sdv_tracing::try_init_tracing() в исполняемом файле.

Библиотека gRPC : libsdvmiddleware_rpc_grpc_transport

События:

  • RPC-клиент: запуск, подключение к серверу и вызовы методов RPC.
  • RPC-сервер: запуск, регистрация в системе обнаружения служб, добавление и вызов методов RPC.

Включение: вызовите sdv_tracing::init_tracing() или sdv_tracing::try_init_tracing() в исполняемом файле.

SOME/IP
  • Процесс: sdv_someip_broker_agent . \
  • События: обработка и перевод сообщений, подписка на события.
менеджер жизненного цикла
  • Процесс: sdv_lifecycle_agent . \
  • События: Операции сервиса — запуск, остановка, регистрация, отмена регистрации.
режим мощности автомобиля
  • Процесс: sdv_vpm_agent . \
  • События: Изменения состояния питания и подписки.
Туннель данных

В будущем мы планируем добавить поддержку отслеживания интеграции.

Накладные расходы на производительность трассировки

При проведении измерений накладных расходов следует учитывать обычную оговорку: производительность может различаться на разных системах, особенно между эмулятором и реальным оборудованием.

Ржавчина

Исходные данные бенчмарка доступны в AOSP . Сбор данных проводился на виртуальной машине Cuttlefish.

  • Одиночный фрагмент: tracing::info_span!() , #[tracing::instrument] и аналогичные:
    • Трассировка неинициализирована: 1 нс.
    • Трассировка инициализирована и отключена (запись трассировки не ведется): 30 нс.
    • Трассировка включена: 3 мкс. Аннотации отладочных полей могут добавить 1-2 мкс в зависимости от сложности преобразования в строку.
  • Отдельные события: tracing::info!() и аналогичные:
    • Трассировка неинициализирована: 1 нс.
    • Трассировка инициализирована и отключена: 30 нс.
    • Трассировка включена: 1,5 мкс. Аннотации отладочных полей могут добавить 0,5–1 мкс в зависимости от сложности stringification .
C++

Показатели производительности взяты из раздела «Производительность» документа «Отслеживание событий» в Perfetto. Время, указанное для Pixel 3 в таблице, соответствует нашим наблюдениям на виртуальной машине Cuttlefish.

Отдельный срез: TRACE_EVENT() и аналогичные функции. Трассировка:

  • Отключено: 2 нс.
  • Включено: 300 нс. Использование аннотаций отладочных полей может добавить 50-100 нс.