Skip to content

Flutter engine should use CPU affinity on Android for better performance #134452

@jonahwilliams

Description

@jonahwilliams

Even on simple apps on Android (like the inappropriately named complex_layout), we seem to occassionally drop frames on the UI thread every so often (Impeller or Skia).

At first I thought it might be a GC or something like that, but looking at perfetto traces I can see that some times the UI thread ends up running on the slow cores of the Pixel 6 Pro 2.80 GHz -> 1.80 GHz . For the scrolling apps that seems to be OK sometimes, unless perhaps some new item needs to be laid out and rendered and then we end up dropping the frame.

Perfetto Trace

image (1)

Release Mode Performance Overlay

The Pixel 6 Pro that I'm using, and many other Android devices use the Arm Big.LITTLE CPU architecture: About half of the cores are "efficiency" cores and are significantly slower ~50% than the other half of the "performance" cores. While the Flutter engine does set priorities of its worker threads to appropriate levels, this does not seem sufficient to ensure that UI/raster workloads are only run on the performance cores.

Furhtermore, the engine uses the concurrency level in many places (IO/Raster worker count) where it would be more appropriate to use the number of fast/slow cores - or about half the concurrency level. This may ultimately be the cause of issues like #132690 and #129392 , but this needs more investigation.

CPU/Thread Affinity Masking

We can force the UI/Raster threads to only run on certain CPUs via

in android_shell_holder.cc

      cpu_set_t set;
      CPU_ZERO(&set);
      CPU_SET(6, &set);
      CPU_SET(7, &set);
      if (sched_setaffinity(gettid(), sizeof(set), &set) != 0) {
        FML_LOG(ERROR) << "Failed to set affinity";
      }

This takes advantage of the fact that I can 1) get the CPU count from sched_getaffinity and 2) am making an assumption that the large CPU indexes are the faster cores. The result of making this change to both Raster/UI threads is that the max UI thread time reported on complex_layout app is about 1/3rd what it used to be:

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work listengineflutter/engine related. See also e: labels.team-engineOwned by Engine teamtriaged-engineTriaged by Engine team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions