This repository was archived by the owner on Feb 25, 2025. It is now read-only.
File tree Expand file tree Collapse file tree 10 files changed +83
-19
lines changed
impeller/renderer/backend/vulkan Expand file tree Collapse file tree 10 files changed +83
-19
lines changed Original file line number Diff line number Diff line change 33// found in the LICENSE file.
44
55#include " flutter/fml/cpu_affinity.h"
6+ #include " flutter/fml/build_config.h"
67
78#include < fstream>
89#include < optional>
910#include < string>
1011
12+ #ifdef FML_OS_ANDROID
13+ #include " flutter/fml/platform/android/cpu_affinity.h"
14+ #endif // FML_OS_ANDROID
15+
1116namespace fml {
1217
18+ std::optional<size_t > EfficiencyCoreCount () {
19+ #ifdef FML_OS_ANDROID
20+ return AndroidEfficiencyCoreCount ();
21+ #else
22+ return std::nullopt ;
23+ #endif
24+ }
25+
26+ bool RequestAffinity (CpuAffinity affinity) {
27+ #ifdef FML_OS_ANDROID
28+ return AndroidRequestAffinity (affinity);
29+ #else
30+ return true ;
31+ #endif
32+ }
33+
1334CPUSpeedTracker::CPUSpeedTracker (std::vector<CpuIndexAndSpeed> data)
1435 : cpu_speeds_(std::move(data)) {
1536 std::optional<int64_t > max_speed = std::nullopt ;
@@ -61,7 +82,6 @@ const std::vector<size_t>& CPUSpeedTracker::GetIndices(
6182// required because files under /proc do not always return a valid size
6283// when using fseek(0, SEEK_END) + ftell(). Nor can they be mmap()-ed.
6384std::optional<int64_t > ReadIntFromFile (const std::string& path) {
64- // size_t data_length = 0u;
6585 std::ifstream file;
6686 file.open (path.c_str ());
6787
Original file line number Diff line number Diff line change @@ -27,6 +27,24 @@ enum class CpuAffinity {
2727 kNotPerformance ,
2828};
2929
30+ // / @brief Request count of efficiency cores.
31+ // /
32+ // / Efficiency cores are defined as those with the lowest reported
33+ // / cpu_max_freq. If the CPU speed could not be determined, or if all
34+ // / cores have the same reported speed then this returns std::nullopt.
35+ // / That is, the result will never be 0.
36+ std::optional<size_t > EfficiencyCoreCount ();
37+
38+ // / @brief Request the given affinity for the current thread.
39+ // /
40+ // / Returns true if successfull, or if it was a no-op. This function is
41+ // / only supported on Android devices.
42+ // /
43+ // / Affinity requests are based on documented CPU speed. This speed data
44+ // / is parsed from cpuinfo_max_freq files, see also:
45+ // / https://www.kernel.org/doc/Documentation/cpu-freq/user-guide.txt
46+ bool RequestAffinity (CpuAffinity affinity);
47+
3048struct CpuIndexAndSpeed {
3149 // The index of the given CPU.
3250 size_t index;
Original file line number Diff line number Diff line change 1212namespace fml {
1313namespace testing {
1414
15+ TEST (CpuAffinity, NonAndroidPlatformDefaults) {
16+ ASSERT_FALSE (fml::EfficiencyCoreCount ().has_value ());
17+ ASSERT_TRUE (fml::RequestAffinity (fml::CpuAffinity::kEfficiency ));
18+ }
19+
1520TEST (CpuAffinity, NormalSlowMedFastCores) {
1621 auto speeds = {CpuIndexAndSpeed{.index = 0 , .speed = 1 },
1722 CpuIndexAndSpeed{.index = 1 , .speed = 2 },
Original file line number Diff line number Diff line change 1111#include < mutex>
1212#include < optional>
1313#include < thread>
14+ #include " flutter/fml/logging.h"
1415
1516namespace fml {
1617
@@ -36,15 +37,27 @@ void InitCPUInfo(size_t cpu_count) {
3637 gCPUTracker = new CPUSpeedTracker (cpu_speeds);
3738}
3839
39- bool RequestAffinity (CpuAffinity affinity ) {
40+ bool SetUpCPUTracker ( ) {
4041 // Populate CPU Info if uninitialized.
4142 auto count = std::thread::hardware_concurrency ();
4243 std::call_once (gCPUTrackerFlag , [count]() { InitCPUInfo (count); });
43- if (gCPUTracker == nullptr ) {
44+ if (gCPUTracker == nullptr || !gCPUTracker ->IsValid ()) {
45+ return false ;
46+ }
47+ return true ;
48+ }
49+
50+ std::optional<size_t > AndroidEfficiencyCoreCount () {
51+ if (!SetUpCPUTracker ()) {
4452 return true ;
4553 }
54+ auto result = gCPUTracker ->GetIndices (CpuAffinity::kEfficiency ).size ();
55+ FML_DCHECK (result > 0 );
56+ return result;
57+ }
4658
47- if (!gCPUTracker ->IsValid ()) {
59+ bool AndroidRequestAffinity (CpuAffinity affinity) {
60+ if (!SetUpCPUTracker ()) {
4861 return true ;
4962 }
5063
Original file line number Diff line number Diff line change 88
99namespace fml {
1010
11- // / @brief Request the given affinity for the current thread.
12- // /
13- // / Returns true if successfull, or if it was a no-op. This function is
14- // / only supported on Android devices.
15- // /
16- // / Affinity requests are based on documented CPU speed. This speed data
17- // / is parsed from cpuinfo_max_freq files, see also:
18- // / https://www.kernel.org/doc/Documentation/cpu-freq/user-guide.txt
19- bool RequestAffinity (CpuAffinity affinity);
11+ // / @brief Android specific implementation of EfficiencyCoreCount.
12+ std::optional<size_t > AndroidEfficiencyCoreCount ();
13+
14+ // / @brief Android specific implementation of RequestAffinity.
15+ bool AndroidRequestAffinity (CpuAffinity affinity);
2016
2117} // namespace fml
Original file line number Diff line number Diff line change 1616#include < string>
1717#include < vector>
1818
19+ #include " flutter/fml/cpu_affinity.h"
1920#include " flutter/fml/trace_event.h"
2021#include " impeller/base/validation.h"
2122#include " impeller/renderer/backend/vulkan/allocator_vk.h"
@@ -130,13 +131,16 @@ void ContextVK::Setup(Settings settings) {
130131
131132 raster_message_loop_ = fml::ConcurrentMessageLoop::Create (
132133 std::min (4u , std::thread::hardware_concurrency ()));
133- #ifdef FML_OS_ANDROID
134134 raster_message_loop_->PostTaskToAllWorkers ([]() {
135+ // Currently we only use the worker task pool for small parts of a frame
136+ // workload, if this changes this setting may need to be adjusted.
137+ fml::RequestAffinity (fml::CpuAffinity::kNotPerformance );
138+ #ifdef FML_OS_ANDROID
135139 if (::setpriority (PRIO_PROCESS, gettid (), -5 ) != 0 ) {
136140 FML_LOG (ERROR) << " Failed to set Workers task runner priority" ;
137141 }
138- });
139142#endif // FML_OS_ANDROID
143+ });
140144
141145 auto & dispatcher = VULKAN_HPP_DEFAULT_DISPATCHER;
142146 dispatcher.init (settings.proc_address_callback );
Original file line number Diff line number Diff line change 88#include < chrono>
99#include < utility>
1010
11+ #include " flutter/fml/cpu_affinity.h"
1112#include " flutter/fml/thread.h"
1213#include " flutter/fml/trace_event.h"
1314#include " impeller/base/validation.h"
@@ -86,8 +87,8 @@ static std::vector<vk::Fence> GetFencesForWaitSet(const WaitSet& set) {
8687void FenceWaiterVK::Main () {
8788 fml::Thread::SetCurrentThreadName (
8889 fml::Thread::ThreadConfig{" io.flutter.impeller.fence_waiter" });
89-
90- using namespace std ::literals::chrono_literals ;
90+ // Since this thread mostly waits on fences, it doesn't need to be fast.
91+ fml::RequestAffinity (fml::CpuAffinity:: kEfficiency ) ;
9192
9293 while (true ) {
9394 // We'll read the terminate_ flag within the lock below.
Original file line number Diff line number Diff line change 44
55#include " impeller/renderer/backend/vulkan/resource_manager_vk.h"
66
7+ #include " flutter/fml/cpu_affinity.h"
78#include " flutter/fml/thread.h"
89#include " flutter/fml/trace_event.h"
910#include " fml/logging.h"
@@ -39,6 +40,9 @@ void ResourceManagerVK::Start() {
3940
4041 fml::Thread::SetCurrentThreadName (
4142 fml::Thread::ThreadConfig{" io.flutter.impeller.resource_manager" });
43+ // While this code calls destructors it doesn't need to be particularly fast
44+ // with them, as long as it doesn't interrupt raster thread.
45+ fml::RequestAffinity (fml::CpuAffinity::kEfficiency );
4246
4347 bool should_exit = false ;
4448 while (!should_exit) {
Original file line number Diff line number Diff line change 1111
1212#include " flutter/common/settings.h"
1313#include " flutter/fml/compiler_specific.h"
14+ #include " flutter/fml/cpu_affinity.h"
1415#include " flutter/fml/logging.h"
1516#include " flutter/fml/mapping.h"
1617#include " flutter/fml/size.h"
@@ -285,7 +286,9 @@ size_t DartVM::GetVMLaunchCount() {
285286DartVM::DartVM (const std::shared_ptr<const DartVMData>& vm_data,
286287 std::shared_ptr<IsolateNameServer> isolate_name_server)
287288 : settings_(vm_data->GetSettings ()),
288- concurrent_message_loop_(fml::ConcurrentMessageLoop::Create()),
289+ concurrent_message_loop_(fml::ConcurrentMessageLoop::Create(
290+ fml::EfficiencyCoreCount ().value_or(
291+ std::thread::hardware_concurrency ()))),
289292 skia_concurrent_executor_(
290293 [runner = concurrent_message_loop_->GetTaskRunner ()](
291294 const fml::closure& work) { runner->PostTask (work); }),
Original file line number Diff line number Diff line change 1616#include < string>
1717#include < utility>
1818
19+ #include " flutter/fml/cpu_affinity.h"
1920#include " flutter/fml/logging.h"
2021#include " flutter/fml/make_copyable.h"
2122#include " flutter/fml/message_loop.h"
2223#include " flutter/fml/native_library.h"
23- #include " flutter/fml/platform/android/cpu_affinity.h"
2424#include " flutter/fml/platform/android/jni_util.h"
2525#include " flutter/lib/ui/painting/image_generator_registry.h"
2626#include " flutter/shell/common/rasterizer.h"
You can’t perform that action at this time.
0 commit comments