aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/IScheduler.cpp
diff options
context:
space:
mode:
authorGeorgios Pinitas <georgios.pinitas@arm.com>2018-02-01 20:23:25 +0000
committerAnthony Barbier <anthony.barbier@arm.com>2018-11-02 16:45:42 +0000
commit53d12277563f860852532ace2a6c796384d969dd (patch)
treee445c005cecea4f44cb2ab51abce82a66181c166 /src/runtime/IScheduler.cpp
parentb7e3028a2bf81ca247895b8550f5a5da02d2483e (diff)
downloadComputeLibrary-53d12277563f860852532ace2a6c796384d969dd.tar.gz
COMPMID-874: Improve default number of threads choice in the Scheduler
Change-Id: Ia30ec2afce0aafcd39f41440efb972b18bbda9f8 Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/118657 Reviewed-by: Anthony Barbier <anthony.barbier@arm.com> Tested-by: Jenkins <bsgcomp@arm.com> Reviewed-by: Pablo Tello <pablo.tello@arm.com>
Diffstat (limited to 'src/runtime/IScheduler.cpp')
-rw-r--r--src/runtime/IScheduler.cpp64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/runtime/IScheduler.cpp b/src/runtime/IScheduler.cpp
index 1d06c4e5e9..583cb40eca 100644
--- a/src/runtime/IScheduler.cpp
+++ b/src/runtime/IScheduler.cpp
@@ -27,13 +27,68 @@
#include <cstdlib>
#include <cstring>
#include <fcntl.h>
+#include <fstream>
+#include <map>
#include <sched.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#ifndef BARE_METAL
+#include <regex>
+#include <thread>
+#endif /* BARE_METAL */
+
namespace
{
+unsigned int get_threads_hint()
+{
+ unsigned int num_threads_hint = 1;
+
+#ifndef BARE_METAL
+ std::map<std::string, unsigned int> cpu_part_occurrence_map;
+
+ // CPU part regex
+ std::regex cpu_part_rgx(R"(.*CPU part.+?(?=:).+?(?=\w+)(\w+).*)");
+ std::smatch cpu_part_match;
+
+ // Read cpuinfo and get occurrence of each core
+ std::ifstream cpuinfo;
+ cpuinfo.open("/proc/cpuinfo", std::ios::in);
+ if(cpuinfo.is_open())
+ {
+ std::string line;
+ while(bool(getline(cpuinfo, line)))
+ {
+ if(std::regex_search(line.cbegin(), line.cend(), cpu_part_match, cpu_part_rgx))
+ {
+ std::string cpu_part = cpu_part_match[1];
+ if(cpu_part_occurrence_map.find(cpu_part) != cpu_part_occurrence_map.end())
+ {
+ cpu_part_occurrence_map[cpu_part]++;
+ }
+ else
+ {
+ cpu_part_occurrence_map[cpu_part] = 1;
+ }
+ }
+ }
+ }
+
+ // Get min number of threads
+ auto min_common_cores = std::min_element(cpu_part_occurrence_map.begin(), cpu_part_occurrence_map.end(),
+ [](const std::pair<std::string, unsigned int> &p1, const std::pair<std::string, unsigned int> &p2)
+ {
+ return p1.second < p2.second;
+ });
+
+ // Set thread hint
+ num_threads_hint = cpu_part_occurrence_map.empty() ? std::thread::hardware_concurrency() : min_common_cores->second;
+#endif /* BARE_METAL */
+
+ return num_threads_hint;
+}
+
unsigned int get_cpu_impl()
{
#ifndef BARE_METAL
@@ -129,6 +184,10 @@ namespace arm_compute
{
IScheduler::IScheduler()
{
+ // Work out the best possible number of execution threads
+ _num_threads_hint = get_threads_hint();
+
+ // Work out the CPU implementation
switch(get_cpu_impl())
{
case 0xd0f:
@@ -161,4 +220,9 @@ CPUInfo IScheduler::cpu_info() const
{
return _info;
}
+
+unsigned int IScheduler::num_threads_hint() const
+{
+ return _num_threads_hint;
+}
} // namespace arm_compute