Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion fml/cpu_affinity.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ const std::vector<size_t>& CPUSpeedTracker::GetIndices(
// required because files under /proc do not always return a valid size
// when using fseek(0, SEEK_END) + ftell(). Nor can they be mmap()-ed.
std::optional<int64_t> ReadIntFromFile(const std::string& path) {
// size_t data_length = 0u;
std::ifstream file;
file.open(path.c_str());

Expand Down
19 changes: 16 additions & 3 deletions fml/platform/android/cpu_affinity.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <mutex>
#include <optional>
#include <thread>
#include "flutter/fml/logging.h"

namespace fml {

Expand All @@ -36,15 +37,27 @@ void InitCPUInfo(size_t cpu_count) {
gCPUTracker = new CPUSpeedTracker(cpu_speeds);
}

bool RequestAffinity(CpuAffinity affinity) {
bool SetUpCPUTracker() {
// Populate CPU Info if uninitialized.
auto count = std::thread::hardware_concurrency();
std::call_once(gCPUTrackerFlag, [count]() { InitCPUInfo(count); });
if (gCPUTracker == nullptr) {
if (gCPUTracker == nullptr || !gCPUTracker->IsValid()) {
return false;
}
return true;
}

std::optional<size_t> EfficiencyCoreCount() {
if (!SetUpCPUTracker()) {
return true;
}
auto result = gCPUTracker->GetIndices(CpuAffinity::kEfficiency).size();
FML_DCHECK(result > 0);
return result;
}

if (!gCPUTracker->IsValid()) {
bool RequestAffinity(CpuAffinity affinity) {
if (!SetUpCPUTracker()) {
return true;
}

Expand Down
8 changes: 8 additions & 0 deletions fml/platform/android/cpu_affinity.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@

namespace fml {

/// @brief Request count of efficiency cores.
///
/// Efficiency cores are defined as those with the lowest reported
/// cpu_max_freq. If the CPU speed could not be determined, or if all
/// cores have the same reported speed then this returns std::nullopt.
/// That is, the result will never be 0.
std::optional<size_t> EfficiencyCoreCount();

/// @brief Request the given affinity for the current thread.
///
/// Returns true if successfull, or if it was a no-op. This function is
Expand Down
4 changes: 4 additions & 0 deletions impeller/renderer/backend/vulkan/context_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <pthread.h>
#include <sys/resource.h>
#include <sys/time.h>
#include "flutter/fml/platform/android/cpu_affinity.h"
#endif // FML_OS_ANDROID

#include <map>
Expand Down Expand Up @@ -132,6 +133,9 @@ void ContextVK::Setup(Settings settings) {
std::min(4u, std::thread::hardware_concurrency()));
#ifdef FML_OS_ANDROID
raster_message_loop_->PostTaskToAllWorkers([]() {
// Currently we only use the worker task pool for small parts of a frame
// workload, if this changes this setting may need to be adjusted.
fml::RequestAffinity(fml::CpuAffinity::kNotPerformance);
if (::setpriority(PRIO_PROCESS, gettid(), -5) != 0) {
FML_LOG(ERROR) << "Failed to set Workers task runner priority";
}
Expand Down
10 changes: 9 additions & 1 deletion impeller/renderer/backend/vulkan/fence_waiter_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
#include <chrono>
#include <utility>

#ifdef FML_OS_ANDROID
#include "flutter/fml/platform/android/cpu_affinity.h"
#include "fml/cpu_affinity.h"
#endif // FML_OS_ANDROID

#include "flutter/fml/thread.h"
#include "flutter/fml/trace_event.h"
#include "impeller/base/validation.h"
Expand Down Expand Up @@ -86,8 +91,11 @@ static std::vector<vk::Fence> GetFencesForWaitSet(const WaitSet& set) {
void FenceWaiterVK::Main() {
fml::Thread::SetCurrentThreadName(
fml::Thread::ThreadConfig{"io.flutter.impeller.fence_waiter"});

#ifdef FML_OS_ANDROID
// Since this thread mostly waits on fences, it doesn't need to be fast.
fml::RequestAffinity(fml::CpuAffinity::kEfficiency);
using namespace std::literals::chrono_literals;
#endif // FML_OS_ANDROID

while (true) {
// We'll read the terminate_ flag within the lock below.
Expand Down
10 changes: 10 additions & 0 deletions impeller/renderer/backend/vulkan/resource_manager_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
#include "flutter/fml/trace_event.h"
#include "fml/logging.h"

#ifdef FML_OS_ANDROID
#include "flutter/fml/platform/android/cpu_affinity.h"
#include "fml/cpu_affinity.h"
#endif // FML_OS_ANDROID

namespace impeller {

std::shared_ptr<ResourceManagerVK> ResourceManagerVK::Create() {
Expand Down Expand Up @@ -39,6 +44,11 @@ void ResourceManagerVK::Start() {

fml::Thread::SetCurrentThreadName(
fml::Thread::ThreadConfig{"io.flutter.impeller.resource_manager"});
#ifdef FML_OS_ANDROID
// While this code calls destructors it doesn't need to be particularly fast
// with them, as long as it doesn't interrupt raster thread.
fml::RequestAffinity(fml::CpuAffinity::kEfficiency);
#endif // FML_OS_ANDROID

bool should_exit = false;
while (!should_exit) {
Expand Down
10 changes: 10 additions & 0 deletions runtime/dart_vm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#include "third_party/tonic/logging/dart_error.h"
#include "third_party/tonic/typed_data/typed_list.h"

#ifdef FML_OS_ANDROID
Copy link
Member

@chinmaygarde chinmaygarde Sep 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the header be safe to include on any platform? The RequestAffinity call can just return false unconditionally on unsupported platforms.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that but #ifdef FML_OS_ANDROID seems to always be false in fml, outside of the platform directory?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to include //flutter/fml/build_config.h to get those definitions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, will give that a shot!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, seems to work. big duh on my part.

#include "flutter/fml/platform/android/cpu_affinity.h"
#endif // FML_OS_ANDROID

namespace dart {
namespace observatory {

Expand Down Expand Up @@ -285,7 +289,13 @@ size_t DartVM::GetVMLaunchCount() {
DartVM::DartVM(const std::shared_ptr<const DartVMData>& vm_data,
std::shared_ptr<IsolateNameServer> isolate_name_server)
: settings_(vm_data->GetSettings()),
#ifdef FML_OS_ANDROID
concurrent_message_loop_(fml::ConcurrentMessageLoop::Create(
fml::EfficiencyCoreCount().value_or(
std::thread::hardware_concurrency()))),
#else
concurrent_message_loop_(fml::ConcurrentMessageLoop::Create()),
#endif // FML_OS_ANDROID
skia_concurrent_executor_(
[runner = concurrent_message_loop_->GetTaskRunner()](
const fml::closure& work) { runner->PostTask(work); }),
Expand Down