Sử dụng tính năng theo dõi để nắm được thông tin chi tiết về hiệu suất hệ thống

Sử dụng tính năng theo dõi để ghi lại các sự kiện và bộ đếm trên hệ thống, đồng thời trực quan hoá từng sự kiện và bộ đếm trên một dòng thời gian. Công cụ theo dõi tiêu chuẩn trong Android là Perfetto. Để tìm hiểu thêm, hãy xem bài viết Theo dõi 101.

Gắn mã theo dõi vào mã của bạn

Để nhận các sự kiện từ ứng dụng, bạn cần phải đo lường bằng cách thêm các điểm theo dõi vào mã. Những phần không được đo lường sẽ không xuất hiện trong dấu vết.

Mẫu theo dõi SDV là một bản minh hoạ về việc tích hợp tính năng theo dõi, cùng với hướng dẫn và ví dụ về cấu hình theo dõi. Nằm ở system/software_defined_vehicle/core_services/samples/tracing/.

Rust

Phương pháp được đề xuất cho Rust là sử dụng thùng tracing để phát ra các sự kiện ATrace. Perfetto hỗ trợ ATrace làm nguồn dữ liệu. Chúng tôi dự định chuyển sang Perfetto SDK khi có các liên kết Rust và tuỳ thuộc vào cách các trường hợp sử dụng phát triển.

Thêm các giá trị mặc định về tính năng theo dõi vào Android.bp:

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

Khởi chạy đối tượng nhận thông báo. Bạn chỉ có thể thực hiện việc này một lần cho mỗi quy trình:

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()
    ...
}

Bạn có thể bỏ qua lệnh gọi khởi tạo. Khi đó, tính năng theo dõi sẽ không được khởi tạo và Perfetto sẽ không thu thập các sự kiện đo lường từ ứng dụng.

Thêm điểm theo dõi. Bạn có thể xem thêm các mẫu trong 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++

Tính năng theo dõi C++ sử dụng SDK Perfetto để theo dõi các sự kiện. Thêm các giá trị mặc định về hoạt động theo dõi vào Android.bp:

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

Xác định các danh mục. Nếu bạn sử dụng các danh mục trên nhiều mô-đun, hãy di chuyển các danh mục đó vào một thư viện chung. Ví dụ: system/software_defined_vehicle/core_services/samples/tracing/cpp_service/tracing_categories.h.

Trong tiêu đề:

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

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

Đặt macro bộ nhớ tĩnh trong tệp nguồn .cpp chứ không phải trong một phương thức. Nếu bạn đang chia sẻ các danh mục trên nhiều thành phần, hãy sử dụng tệp nguồn tương ứng với tiêu đề có danh mục.

PERFETTO_TRACK_EVENT_STATIC_STORAGE();

int main() {
    ...
}

Để khởi động Perfetto, hãy khởi động phụ trợ hệ thống và đăng ký các sự kiện theo dõi:


#include <sdv/tracing_init.h>

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

Thêm tính năng đo lường. Xem thêm các mẫu trong 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;
}

Như trong ví dụ về Rust, mã này tạo ra 2 lát cắt lồng nhau và một điểm đánh dấu cho sự kiện tức thì trong giao diện người dùng. Các giá trị đối số gỡ lỗi sẽ xuất hiện khi bạn chọn một sự kiện.

Thu thập dấu vết

Sử dụng tập lệnh dòng lệnh record\_android\_trace để ghi lại dấu vết và giao diện người dùng web Perfetto để xem dấu vết đó.

Định cấu hình chế độ chụp

Bạn cần cung cấp một cấu hình cho record_android_trace ở định dạng textproto. Hãy xem tài liệu Perfetto để tìm hiểu thêm.

Kho lưu trữ SDV chứa một cấu hình mẫu (system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx). Tệp này bao gồm một số nguồn dữ liệu và có thể được tuỳ chỉnh hoặc sử dụng nguyên trạng.

Dùng giao diện người dùng Perfetto để tạo cấu hình

Bạn có thể định cấu hình một cấu hình tuỳ chỉnh và khám phá các lựa chọn hiện có bằng cách chuyển đến Record new trace (Ghi lại dấu vết mới) trong giao diện người dùng Perfetto, điều chỉnh chế độ cài đặt ghi và các lệnh dò tìm. Sau đó, bạn có thể mở chế độ xem "Lệnh ghi" để xem lệnh đã tạo và lấy nội dung cấu hình từ đó.

Định cấu hình khả năng hiển thị tính năng đo lường trong ứng dụng

Hoạt động đo lường Rust sử dụng ATrace. Thành phần này được định cấu hình trong phần ftrace_config của tài liệu. Các thành phần SDV có thẻ ATRACE_TAG_APP và có thể được bật theo từng ứng dụng. Cấu hình mẫu này cho phép tất cả các ứng dụng.

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

Chúng ta sử dụng các sự kiện theo dõi trong Perfetto SDK C++. Đây là một nguồn dữ liệu track_event (tài liệu).

Bạn có thể bật hoặc tắt danh mục và thẻ trong trường track_event_config. Theo mặc định, mọi thẻ đóng danh mục đều được bật, ngoại trừ các thẻ đặc biệt slowdebug. Nếu chỉ muốn bật một số danh mục cụ thể, bạn cần tắt tất cả các danh mục khác, chẳng hạn như bằng disabled_categories: "*" như ở đây:

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

Ghi lại dấu vết

Mở một cửa sổ dòng lệnh ở gốc kho lưu trữ Android. Bạn không cần thực hiện envsetup. Tập lệnh ghi nằm trong external/perfetto/tools/record_android_trace.

Chạy tập lệnh bằng cấu hình mẫu:

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

Để dừng ghi sớm, hãy chọn Ctrl + C.

Thao tác này sẽ kích hoạt adb shell perfetto để ghi lại dấu vết, sau đó kéo dấu vết đó vào máy chủ lưu trữ, thường là trong ~/traces. Khi dấu vết được thu thập, công cụ này sẽ mở một cửa sổ trình duyệt để hiển thị dấu vết.

Đối số hữu ích:

  • -s SERIAL để sử dụng thiết bị có số sê-ri nhất định. Ví dụ: -s 0.0.0.0:6520

  • --no-open-browser sẽ tạo một URL để phân phát dấu vết nhưng sẽ không mở trình duyệt. Điều này hữu ích cho các phiên từ xa khi bạn đã thiết lập tính năng chuyển tiếp cổng (thường là 9001).

  • -n, --no-open sẽ không mở trình duyệt hoặc tạo URL để phân phát dấu vết sau phiên theo dõi. Bạn vẫn có thể mở các tệp trong giao diện người dùng Perfetto bằng cách nhấp vào "Mở tệp theo dõi" rồi chọn tệp.

  • -o <path> để đặt đường dẫn đầu ra.

Chi tiết sử dụng

Phần này cung cấp thông tin chi tiết có thể hữu ích khi sử dụng hệ thống theo dõi.

Đo lường dấu vết trong các thành phần SDV

Trong các tác nhân có tính năng đo lường theo dõi, tính năng theo dõi sẽ có sẵn theo mặc định trên các bản dựng có thể gỡ lỗi (-eng, -userdebug), trừ phi được chỉ định khác. Khi thu thập dấu vết, bạn sẽ thấy các sự kiện cho các quy trình mà không cần cấu hình bổ sung.

Thông thường, các thư viện không tự động khởi động tính năng theo dõi. Trong Rust, tệp nhị phân sử dụng thư viện cần khởi động tính năng theo dõi cho quy trình bằng cách sử dụng sdv_tracing::init_tracing(). Hãy tham khảo phần Gắn mã theo dõi cho mã của bạn để tìm hiểu thêm.

Phần mềm trung gian

Thư viện xuất bản/đăng ký: libsdv_middleware_dt

Sự kiện:

  • Nhà xuất bản: Xuất bản và đăng ký chủ đề.
  • Người đăng ký: Đăng ký và bỏ phiếu.

Bật: Gọi sdv_tracing::init_tracing() hoặc sdv_tracing::try_init_tracing() trong tệp nhị phân.

Thư viện gRPC: libsdvmiddleware_rpc_grpc_transport

Sự kiện:

  • Máy khách RPC: Bắt đầu, kết nối với máy chủ và gọi phương thức RPC.
  • Máy chủ RPC: Bắt đầu, đăng ký với Dịch vụ khám phá, thêm và gọi các phương thức RPC.

Bật: Gọi sdv_tracing::init_tracing() hoặc sdv_tracing::try_init_tracing() ở dạng nhị phân.

SOME/IP
  • Quy trình: sdv_someip_broker_agent. \
  • Sự kiện: Xử lý và dịch tin nhắn, đăng ký sự kiện.
Trình quản lý vòng đời
  • Quy trình: sdv_lifecycle_agent. \
  • Sự kiện: Thao tác dịch vụ – khởi chạy, dừng, đăng ký, huỷ đăng ký.
Chế độ nguồn của xe
  • Quy trình: sdv_vpm_agent. \
  • Sự kiện: Thay đổi trạng thái nguồn và gói thuê bao.
Đường hầm dữ liệu

Chúng tôi dự định sẽ hỗ trợ tích hợp tính năng theo dõi trong thời gian tới.

Chi phí hiệu suất của hoạt động theo dõi

Các phép đo chi phí chung đi kèm với cảnh báo thông thường rằng hiệu suất có thể khác nhau giữa các hệ thống và đặc biệt là giữa trình mô phỏng và phần cứng thực.

Rust

Dữ liệu điểm chuẩn thô có trong AOSP. Dữ liệu được thu thập trên một VM Cuttlefish.

  • Một nhịp: tracing::info_span!(), #[tracing::instrument] và các nhịp tương tự:
    • Theo dõi chưa khởi chạy: 1 mili giây.
    • Đã khởi chạy và tắt tính năng theo dõi (không ghi lại dấu vết): 30 mili giây.
    • Đã bật tính năng theo dõi: 3 µs. Chú thích gỡ lỗi trường có thể thêm 1-2 µs, tuỳ thuộc vào độ phức tạp của quá trình chuyển đổi thành chuỗi.
  • Sự kiện đơn lẻ: tracing::info!() và các sự kiện tương tự:
    • Theo dõi chưa khởi chạy: 1 mili giây.
    • Đã khởi chạy và tắt tính năng theo dõi: 30 nano giây.
    • Đã bật tính năng theo dõi: 1,5 µs. Chú thích trường gỡ lỗi có thể thêm 0,5 – 1 µs, tuỳ thuộc vào độ phức tạp của stringification.
C++

Các số liệu về hiệu suất được lấy từ phần Hiệu suất của tài liệu Sự kiện theo dõi trong Perfetto. Thời gian cho Pixel 3 trong bảng nhất quán với những gì chúng tôi quan sát được trên VM Cuttlefish.

Một lát: TRACE_EVENT() và tương tự. Truy tìm:

  • Đã tắt: 2 giây.
  • Đã bật: 300 nano giây. Việc sử dụng chú giải trường gỡ lỗi có thể thêm 50-100 ns.