使用追蹤記錄深入瞭解系統效能

您可以使用追蹤功能記錄系統上的事件和計數器,並在時間軸上顯示每個項目。Android 的標準追蹤工具是 Perfetto。如要瞭解詳情,請參閱「追蹤 101」。

檢測程式碼

如要從應用程式取得事件,必須在程式碼中加入追蹤點,才能進行檢測。未經過插碼的區段不會顯示在追蹤記錄中。

SDV 追蹤範例是追蹤整合的試用版,內含操作說明和追蹤設定範例。位於 system/software_defined_vehicle/core_services/samples/tracing/

Rust

建議您使用 Rust 的 tracing Crate 發出 ATrace 事件。Perfetto 支援 ATrace 做為資料來源。我們計畫在 Rust 繫結推出後,視用途演變情況改用 Perfetto SDK。

將追蹤預設值新增至 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 範例,這段程式碼會產生兩個巢狀切片,以及 UI 中即時事件的標記。選取事件時,系統會顯示偵錯引數值。

收集追蹤記錄

使用 record\_android\_trace 指令列指令碼記錄追蹤記錄,並使用 Perfetto 網頁 UI 查看。

設定擷取作業

您需要以 textproto 格式提供 record_android_trace 的設定。詳情請參閱 Perfetto 文件

SDV 存放區包含範例設定 (system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx)。這個檔案包含多個資料來源,可自訂或直接使用。

使用 Perfetto UI 產生設定

您可以前往 Perfetto UI 中的「Record new trace」(記錄新追蹤記錄),調整記錄設定和探針,設定自訂設定並探索可用選項。接著開啟「Recording command」(錄音指令) 檢視畫面,查看產生的指令,並從中取得設定內容。

設定應用程式內檢測功能的可見度

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: "*"
        }
    }
}

我們在 C++ Perfetto SDK 中使用追蹤事件。這是 track_event 資料來源 (文件)。

您可以在 track_event_config 欄位中啟用或停用類別和標記。除了特殊 slowdebug 標記之外,系統預設會啟用每個類別的結尾標記。如果只想啟用特定類別,請停用所有其他類別,例如使用 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 會建立用於提供追蹤記錄的網址,但不會開啟瀏覽器。如果您已設定通訊埠轉送 (通常是 9001),這項功能在遠端工作階段中會很有用。

  • -n, --no-open 不會在追蹤工作階段後開啟瀏覽器或建立網址來提供追蹤記錄。您還是可以點選「Open trace file」並選取檔案,在 Perfetto UI 中開啟檔案。

  • -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 伺服器:啟動、向 Service Discovery 註冊、新增及呼叫 RPC 方法。

啟用:在二進位檔中呼叫 sdv_tracing::init_tracing()sdv_tracing::try_init_tracing()

SOME/IP
  • 程序:sdv_someip_broker_agent。\
  • 事件:訊息處理和翻譯、事件訂閱。
生命週期管理工具
  • 程序:sdv_lifecycle_agent。\
  • 事件:服務作業 - 啟動、停止、註冊、取消註冊。
車輛動力模式
  • 程序:sdv_vpm_agent。\
  • 事件:電源狀態變更和訂閱。
資料通道

我們預計在日後支援追蹤整合。

追蹤的效能負擔

照常提醒,不同系統的負荷測量結果可能有所差異,模擬器和實際硬體之間的差異尤其明顯。

Rust

原始基準資料可在 AOSP 中取得。這些資料是在 Cuttlefish VM 上收集。

  • 單一跨度:tracing::info_span!()#[tracing::instrument] 和類似項目:
    • 追蹤未初始化:1 奈秒。
    • 追蹤已初始化並停用 (未錄製任何追蹤記錄):30 奈秒。
    • 已啟用追蹤:3 微秒。偵錯欄位註解可能會增加 1 到 2 微秒,視字串化複雜度而定。
  • 單一事件:tracing::info!() 和類似事件:
    • 追蹤未初始化:1 奈秒。
    • 追蹤功能已初始化並停用:30 奈秒。
    • 已啟用追蹤:1.5 微秒。視 stringification 複雜度而定,偵錯欄位註解可能會增加 0.5 到 1 微秒。
C++

效能數字來自 Perfetto 的「追蹤事件」文件效能部分。表中的 Pixel 3 時間與我們在 Cuttlefish VM 上的觀察結果一致。

單一配量:TRACE_EVENT() 和類似項目。追蹤:

  • 已停用:2 秒。
  • 已啟用:300 奈秒。使用偵錯欄位註解可能會增加 50 到 100 奈秒。