सिस्टम की परफ़ॉर्मेंस के बारे में अहम जानकारी पाने के लिए, ट्रेसिंग का इस्तेमाल करना

सिस्टम पर इवेंट और काउंटर रिकॉर्ड करने के लिए, ट्रेसिंग का इस्तेमाल करें. साथ ही, हर इवेंट और काउंटर को टाइमलाइन पर विज़ुअलाइज़ करें. Android में, Perfetto, स्टैंडर्ड ट्रेसिंग टूल है. ज़्यादा जानने के लिए, ट्रेसिंग 101 लेख पढ़ें.

अपने कोड को इंस्ट्रूमेंट करना

ऐप्लिकेशन से इवेंट पाने के लिए, कोड में ट्रेसपॉइंट जोड़कर उसे इंस्ट्रूमेंट करना ज़रूरी है. जिन सेक्शन को इंस्ट्रूमेंट नहीं किया गया है वे ट्रेस में नहीं दिखेंगे.

एसडीवी ट्रेसिंग का सैंपल, ट्रेसिंग इंटिग्रेशन का डेमो है. इसमें निर्देश और ट्रेसिंग कॉन्फ़िगरेशन का एक उदाहरण भी शामिल है. यह system/software_defined_vehicle/core_services/samples/tracing/ में मौजूद है.

रस्ट

ज़ंग के लिए, ट्रेसिंग क्रेट का इस्तेमाल करके 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 के उदाहरण की तरह, यह कोड यूज़र इंटरफ़ेस (यूआई) में, दो नेस्टेड स्लाइस और इंस्टैंट इवेंट के लिए एक मार्कर बनाता है. किसी इवेंट को चुनने पर, डीबग आर्ग्युमेंट की वैल्यू दिखती हैं.

ट्रेस इकट्ठा करना

ट्रेस रिकॉर्ड करने के लिए, record\_android\_trace कमांड लाइन स्क्रिप्ट का इस्तेमाल करें. साथ ही, इसे देखने के लिए Perfetto वेब यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करें.

कैप्चर करने की सुविधा को कॉन्फ़िगर करना

record_android_trace के लिए, textproto फ़ॉर्मैट में कॉन्फ़िगरेशन देना ज़रूरी है. ज़्यादा जानने के लिए, Perfetto का दस्तावेज़ देखें.

एसडीवी रिपॉज़िटरी में, कॉन्फ़िगरेशन का एक सैंपल (system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx) मौजूद है. इस फ़ाइल में, डेटा सोर्स शामिल हैं. इसे अपनी ज़रूरत के हिसाब से बदला जा सकता है या इसका इस्तेमाल ऐसे ही किया जा सकता है.

कॉन्फ़िगरेशन जनरेट करने के लिए, Perfetto यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करना

Perfetto यूज़र इंटरफ़ेस (यूआई) में, नया ट्रेस रिकॉर्ड करें पर जाकर, कस्टम कॉन्फ़िगरेशन सेट किया जा सकता है. साथ ही, उपलब्ध विकल्पों को एक्सप्लोर किया जा सकता है. इसके अलावा, रिकॉर्डिंग सेटिंग और प्रोब में बदलाव किया जा सकता है. इसके बाद, जनरेट किया गया कमांड देखने और वहां से कॉन्फ़िगरेशन का कॉन्टेंट पाने के लिए, "रिकॉर्डिंग कमांड" व्यू खोला जा सकता है.

ऐप्लिकेशन में इंस्ट्रूमेंटेशन की विज़िबिलिटी कॉन्फ़िगर करना

Rust इंस्ट्रूमेंटेशन, ATrace का इस्तेमाल करता है. इसे दस्तावेज़ के ftrace_config सेक्शन में कॉन्फ़िगर किया जाता है. एसडीवी कॉम्पोनेंट में, 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 से, ट्रेस दिखाने के लिए एक यूआरएल बनेगा, लेकिन ब्राउज़र नहीं खुलेगा. यह रिमोट सेशन के लिए काम का है, जब पोर्ट फ़ॉरवर्डिंग (आम तौर पर 9001) सेट अप किया गया हो.

  • -n, --no-open से, ट्रेसिंग सेशन के बाद, ब्राउज़र नहीं खुलेगा. साथ ही, ट्रेस दिखाने के लिए यूआरएल नहीं बनेगा. Perfetto यूज़र इंटरफ़ेस (यूआई) में, "ट्रेस फ़ाइल खोलें" पर क्लिक करके और फ़ाइल चुनकर, अब भी फ़ाइलें खोली जा सकती हैं.

  • आउटपुट पाथ सेट करने के लिए, -o <path>.

इस्तेमाल की जानकारी

इस सेक्शन में, ट्रेसिंग सिस्टम का इस्तेमाल करते समय काम की जानकारी दी गई है.

एसडीवी कॉम्पोनेंट में, ट्रेस इंस्ट्रूमेंटेशन

ट्रेसिंग इंस्ट्रूमेंटेशन वाले एजेंट में, डीबग किए जा सकने वाले बिल्ड (-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. 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
  • इवेंट: पावर स्टेट में बदलाव और सदस्यताएं.
डेटा टनल

हम आने वाले समय में, ट्रेसिंग इंटिग्रेशन की सुविधा उपलब्ध कराने की योजना बना रहे हैं.

ट्रेसिंग का परफ़ॉर्मेंस ओवरहेड

ओवरहेड मेज़रमेंट के साथ, यह सामान्य चेतावनी भी दी जाती है कि अलग-अलग सिस्टम में परफ़ॉर्मेंस अलग-अलग हो सकती है. खास तौर पर, एम्युलेटर और असली हार्डवेयर के बीच परफ़ॉर्मेंस में अंतर हो सकता है.

रस्ट

बेंचमार्क का रॉ डेटा, AOSP में उपलब्ध है. यह डेटा, Cuttlefish VM पर इकट्ठा किया गया था.

  • सिंगल स्पैन: tracing::info_span!(), #[tracing::instrument] वगैरह:
    • ट्रेसिंग शुरू नहीं की गई: 1ns.
    • ट्रेसिंग शुरू की गई और बंद की गई (कोई ट्रेस रिकॉर्ड नहीं किया जा रहा है): 30ns.
    • ट्रेसिंग चालू की गई: 3 µs. डीबग फ़ील्ड एनोटेशन में 1-2 µs लग सकते हैं, स्ट्रिंगिफ़िकेशन की जटिलता के आधार पर.
  • सिंगल इवेंट: tracing::info!() वगैरह:
    • ट्रेसिंग शुरू नहीं की गई: 1ns.
    • ट्रेसिंग शुरू की गई और बंद की गई: 30ns.
    • ट्रेसिंग चालू की गई: 1.5 µs. stringification की जटिलता के आधार पर, डीबग फ़ील्ड एनोटेशन में 0.5-1 µs लग सकते हैं.
C++

परफ़ॉर्मेंस के आंकड़े, Perfetto में ट्रैक इवेंट दस्तावेज़ के परफ़ॉर्मेंस सेक्शन से लिए गए हैं. टेबल में Pixel 3 के लिए दिए गए समय, Cuttlefish VM पर हमारे ऑब्ज़र्वेशन के मुताबिक हैं.

सिंगल स्लाइस: TRACE_EVENT() वगैरह. ट्रेसिंग:

  • बंद की गई: 2ns.
  • चालू की गई: 300ns. डीबग फ़ील्ड एनोटेशन का इस्तेमाल करने पर, 50-100ns लग सकते हैं.