ใช้การติดตามเพื่อรับข้อมูลเชิงลึกเกี่ยวกับประสิทธิภาพของระบบ

ใช้การติดตามเพื่อบันทึกเหตุการณ์และตัวนับในระบบ รวมถึงแสดงภาพแต่ละรายการในไทม์ไลน์ เครื่องมือการติดตามมาตรฐานใน Android คือ Perfetto ดูข้อมูลเพิ่มเติมได้ที่ Tracing 101

เพิ่มเครื่องมือวัดประสิทธิภาพโค้ด

หากต้องการรับเหตุการณ์จากแอป คุณต้องเพิ่มเครื่องมือวัดประสิทธิภาพโค้ดโดยการเพิ่มจุดติดตามลงในโค้ด ส่วนที่ไม่ได้เพิ่มเครื่องมือวัดประสิทธิภาพโค้ดจะไม่ปรากฏในการติดตาม

ตัวอย่างการติดตาม SDV เป็นการสาธิตการผสานรวมการติดตาม พร้อมด้วยวิธีการและตัวอย่างการกำหนดค่าการติดตาม ซึ่งอยู่ใน system/software_defined_vehicle/core_services/samples/tracing/

สนิม

แนวทางที่แนะนำสำหรับ Rust คือการใช้กล่องเครื่องมือการติดตามเพื่อส่ง เหตุการณ์ ATrace Perfetto รองรับ ATrace เป็นแหล่งข้อมูล เราวางแผนที่จะเปลี่ยนไปใช้ Perfetto SDK เมื่อมีการผูก 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 โค้ดนี้จะสร้างสไลซ์ที่ซ้อนกัน 2 รายการและเครื่องหมายสำหรับเหตุการณ์ทันทีใน UI ค่าอาร์กิวเมนต์การแก้ไขข้อบกพร่องจะแสดงขึ้นเมื่อมีการเลือกเหตุการณ์

เก็บรวบรวมการติดตาม

ใช้สคริปต์บรรทัดคำสั่ง record\_android\_trace เพื่อบันทึกการติดตาม และ Perfetto เว็บ UI เพื่อดูการติดตาม

กำหนดค่าการบันทึก

คุณต้องระบุการกำหนดค่าสำหรับ record_android_trace ในรูปแบบ textproto ดูข้อมูลเพิ่มเติมได้ที่ เอกสารประกอบของ Perfetto

ที่เก็บ SDV มีการกำหนดค่าตัวอย่าง (system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx) ไฟล์นี้มีแหล่งข้อมูลหลายแหล่งและสามารถปรับแต่งหรือใช้ได้ตามต้องการ

ใช้ UI ของ Perfetto เพื่อสร้างการกำหนดค่า

คุณกำหนดค่าที่กำหนดเองและสำรวจตัวเลือกที่มีได้โดยไปที่ บันทึกการติดตามใหม่ ใน Perfetto UI แล้วปรับการตั้งค่าการบันทึกและโพรบ จากนั้นคุณจะเปิดมุมมอง "คำสั่งการบันทึก" เพื่อดูคำสั่งที่สร้างขึ้นและรับเนื้อหาการกำหนดค่า จากที่นั่นได้

กำหนดค่าระดับการเข้าถึงเครื่องมือวัดประสิทธิภาพโค้ดในแอป

เครื่องมือวัดประสิทธิภาพโค้ด 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 ระบบจะเปิดใช้แท็กสิ้นสุดของทุกหมวดหมู่โดยค่าเริ่มต้น ยกเว้นแท็ก 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 เพื่อแสดงการติดตามหลังจากเซสชันการติดตาม คุณยังคงเปิดไฟล์ใน UI ของ 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: การเริ่มต้น การลงทะเบียนกับ Service Discovery การเพิ่มและการเรียกใช้เมธอด RPC

การเปิดใช้: เรียก sdv_tracing::init_tracing() หรือ sdv_tracing::try_init_tracing() ในไบนารี

SOME/IP
  • กระบวนการ: sdv_someip_broker_agent Example Source: This is a test Example Translation: Dies ist ein Test Source: This is a test with another placeholder Translation: Dies ist ein Test mit einem anderen Platzhalter
  • เหตุการณ์: การประมวลผลและการแปลข้อความ การสมัครใช้บริการเหตุการณ์
ตัวจัดการวงจร
  • กระบวนการ: sdv_lifecycle_agent Example Source: This is a test Example Translation: Dies ist ein Test Source: This is a test with another placeholder Translation: Dies ist ein Test mit einem anderen Platzhalter
  • เหตุการณ์: การดำเนินการบริการ - การเปิดใช้ การหยุด การลงทะเบียน การยกเลิกการลงทะเบียน
โหมดพลังงานของยานพาหนะ
  • กระบวนการ: sdv_vpm_agent Example Source: This is a test Example Translation: Dies ist ein Test Source: This is a test with another placeholder Translation: Dies ist ein Test mit einem anderen Platzhalter
  • เหตุการณ์: การเปลี่ยนแปลงสถานะพลังงานและการสมัครใช้บริการ
Data Tunnel

เราวางแผนที่จะรองรับการผสานรวมการติดตามในอนาคต

ค่าใช้จ่ายด้านประสิทธิภาพของการติดตาม

การวัดค่าใช้จ่ายมาพร้อมกับข้อควรระวังตามปกติที่ว่าประสิทธิภาพอาจแตกต่างกันไปในแต่ละระบบ และโดยเฉพาะอย่างยิ่งระหว่างโปรแกรมจำลองกับฮาร์ดแวร์จริง

สนิม

ข้อมูลการวัดประสิทธิภาพดิบมีอยู่ใน AOSP ข้อมูลได้รับการเก็บรวบรวมใน VM ของ Cuttlefish

  • ช่วงเดียว: tracing::info_span!(), #[tracing::instrument] และอื่นๆ ที่คล้ายกัน
  • เหตุการณ์เดียว: tracing::info!() และอื่นๆ ที่คล้ายกัน
    • การติดตามไม่ได้เริ่มต้น: 1ns
    • การติดตามเริ่มต้นและปิดใช้: 30ns
    • การติดตามเปิดใช้: 1.5 µs คำอธิบายประกอบของฟิลด์การแก้ไขข้อบกพร่องอาจเพิ่ม 0.5-1 µs, ขึ้นอยู่กับความซับซ้อนstringification
C++

ตัวเลขประสิทธิภาพมาจากส่วนประสิทธิภาพของเอกสารประกอบเหตุการณ์การติดตาม ใน Perfetto เวลาสำหรับ Pixel 3 ในตารางสอดคล้องกับการสังเกตของเราใน VM ของ Cuttlefish

สไลซ์เดียว: TRACE_EVENT() และอื่นๆ ที่คล้ายกัน การติดตาม

  • ปิดใช้: 2ns
  • เปิดใช้: 300ns การใช้คำอธิบายประกอบของฟิลด์การแก้ไขข้อบกพร่องอาจเพิ่ม 50-100ns