Profiling the engine - flutter-tizen/flutter-tizen GitHub Wiki

Profiling the engine with Linux perf

Note: You need a rooted device (such as a Raspberry Pi) to use perf. You can't use emulators for profiling purposes because Dart doesn't support x86 AOT.

Building perf

  1. Download the kernel source code for your target device (e.g. platform/kernel/linux-rpi for Raspberry Pi 4).

  2. Locate the perf tool (tools/perf) in the kernel source code. We will cross build it via Docker ARM emulation. You can alternatively use GBS if you're familiar with it.

  3. Install Docker and QEMU packages on your host machine by referring to Install Docker Engine on Ubuntu and Running and Building ARM Docker Containers on x86.

  4. Run a Docker container of your device's architecture. For example, if your device is an arm64 Raspberry Pi, run

    docker run --rm -ti --platform linux/arm64 -v [path_to_repo]:/linux-rpi arm64v8/debian:buster bash
  5. Build perf by running the following commands.

    apt update
    apt install make gcc bison flex
    apt install libelf-dev libdw-dev systemtap-sdt-dev libunwind-dev \
                libssl-dev python3 libiberty-dev libzstd-dev libcap-dev
    cd /linux-rpi/tools/perf
    make clean
    make
  6. Once the build is done, copy the output executable (perf) to your device.

    sdb root on
    sdb push perf /home/owner/perf

Collecting perf data on app startup

  1. Build your app in release mode with unstripped engine and embedder artifacts (by referring to Debugging the engine and embedder) and install to your device.

  2. Open the sdb shell and type the following commands as root. (Replace ELM_PROFILE with your device's profile.)

    echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    export ELM_ENGINE=wayland_egl
    export ELM_DISPLAY=wl
    export HOME=/opt/usr/home/owner
    export ELM_PROFILE=common
    export XDG_RUNTIME_DIR=/run/user/5001
    export DBUS_SESSION_BUS_ADDRESS="kernel:path=/sys/fs/kdbus/5001-user/bus;unix:path=/run/user/5001/bus"
  3. Launch the app under perf. For example, if the app is a native app and its app ID is io.flutter.demo.gallery, run

    cd /home/owner
    AUL_APPID=io.flutter.demo.gallery ./perf record -v -F 5000 -g /opt/usr/globalapps/io.flutter.demo.gallery/bin/runner

    Note: In case of a .NET application, replace /opt/usr/.../runner with dotnet-launcher --standalone /opt/usr/.../Runner.dll.

  4. Once the app appears on the device screen, stop tracing by pressing Ctrl+C.

  5. Process the raw sampling data (perf.data).

    ./perf script > perf.script
  6. Copy the file to your host machine.

    sdb pull /home/owner/perf.script

Visualizing the perf data

The recorded perf data can be opened by various tools available online. Among them, the following two are recommended.

  1. Firefox Profiler

    Drag and drop the perf.script file into the Firefox Profiler web UI.

  2. FlameGraph

    Clone the repository and run the following commands to convert perf.script into a .svg file which can be opened by your browser.

    cat perf.script | ./stackcollapse-perf.pl > out.perf-folded
    cat out.perf-folded | ./flamegraph.pl > perf-kernel.svg
    

Tracing the engine with DevTools

Caution: This method is outdated as of Flutter 2.5. Native symbols will not be resolved correctly even if you apply the following or any other methods suggested in https://github.com/flutter-tizen/engine/issues/95.

You can skip steps 1-2 and 6-7 if you don't need native stack traces but only want to trace events from the Dart code (framework).

  1. Build the engine from source in profile mode. Before running the build, make sure to enable the enable_profiling flag by applying this patch.

  2. Once the build is done, find unstripped build artifacts (so.unstripped) from the output directory, and copy them to flutter-tizen's cached artifacts directory (flutter-tizen/flutter/bin/cache/artifacts/engine).

  3. Build and run your app in profile mode.

    flutter-tizen run --profile
  4. Open DevTools and go to the Performance tab.

  5. Let your app draw some frames and click one of the colored bars displayed in the FPS chart.

  6. Click CPU Flame Chart in the below CPU Profile view. In the top right of the view, click the Filter icon (image) and make sure Hide Native code is unchecked.

  7. Check if native symbols are displayed correctly in the CPU Flame Chart.

  8. You can also use the CPU Profiler tab if you want to profile the app only for a specific duration. See Flutter Docs: CPU Profiler view for details.

⚠️ **GitHub.com Fallback** ⚠️