From 7fad9b1d00f3ee1488ba4038d1371f6ea219f8b7 Mon Sep 17 00:00:00 2001 From: Pablo Tello Date: Wed, 14 Mar 2018 17:55:27 +0000 Subject: COMPMID-1021: CPUInfo refactoring. Removed CPUTarget in favor of the CPUModel type. CPUInfo now holds a vector of N CPUs. CPUInfo autoinitialise upon construction with 1 GENERIC CPU. CPPScheduler fills CPUInfo's vector upon construction (runtime). IScheduler has a single CPUInfo obj and ThreadInfo always gets a pointer to it (avoid copying the vector) Change-Id: I30f293258c959c87f6bac5eac8b963beb6a4d365 Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/124626 Tested-by: Jenkins Reviewed-by: Anthony Barbier --- src/runtime/IScheduler.cpp | 190 +-------------------------------------------- 1 file changed, 4 insertions(+), 186 deletions(-) (limited to 'src/runtime/IScheduler.cpp') diff --git a/src/runtime/IScheduler.cpp b/src/runtime/IScheduler.cpp index 583cb40eca..54a2bd2182 100644 --- a/src/runtime/IScheduler.cpp +++ b/src/runtime/IScheduler.cpp @@ -23,202 +23,20 @@ */ #include "arm_compute/runtime/IScheduler.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef BARE_METAL -#include -#include -#endif /* BARE_METAL */ - -namespace -{ -unsigned int get_threads_hint() -{ - unsigned int num_threads_hint = 1; - -#ifndef BARE_METAL - std::map 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 &p1, const std::pair &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 - int fd = open("/proc/cpuinfo", 0); // NOLINT - std::array buff{ {} }; - char *pos = nullptr; - char *end = nullptr; - bool foundid = false; - - int cpu = sched_getcpu(); - - if(fd == -1) - { - return 0; - } - - int charsread = read(fd, buff.data(), 3000); - pos = buff.data(); - end = buff.data() + charsread; - - close(fd); - - /* So, to date I've encountered two formats for /proc/cpuinfo. - * - * One of them just lists processor : n for each processor (with no - * other info), then at the end lists part information for the current - * CPU. - * - * The other has an entire clause (including part number info) for each - * CPU in the system, with "processor : n" headers. - * - * We can cope with either of these formats by waiting to see - * "processor: n" (where n = our CPU ID), and then looking for the next - * "CPU part" field. - */ - while(pos < end) - { - if(foundid && strncmp(pos, "CPU part", 8) == 0) - { - /* Found part number */ - pos += 11; - - for(char *ch = pos; ch < end; ch++) - { - if(*ch == '\n') - { - *ch = '\0'; - break; - } - } - - return strtoul(pos, nullptr, 0); - } - - if(strncmp(pos, "processor", 9) == 0) - { - /* Found processor ID, see if it's ours. */ - pos += 11; - - for(char *ch = pos; ch < end; ch++) - { - if(*ch == '\n') - { - *ch = '\0'; - break; - } - } - - int num = strtol(pos, nullptr, 0); - - if(num == cpu) - { - foundid = true; - } - } - - while(pos < end) - { - char ch = *pos++; - if(ch == '\n' || ch == '\0') - { - break; - } - } - } -#endif /* BARE_METAL */ - - return 0; -} -} // namespace +#include "arm_compute/runtime/CPUUtils.h" namespace arm_compute { IScheduler::IScheduler() + : _cpu_info() { // 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: - _info.CPU = CPUTarget::A55_DOT; - break; - case 0xd03: - _info.CPU = CPUTarget::A53; - break; - default: -#ifdef __arm__ - _info.CPU = CPUTarget::ARMV7; -#elif __aarch64__ - _info.CPU = CPUTarget::ARMV8; -#else /* __arm__ || __aarch64__ */ - _info.CPU = CPUTarget::INTRINSICS; -#endif /* __arm__ || __aarch64__ */ - break; - } - - _info.L1_size = 31000; - _info.L2_size = 500000; -} - -void IScheduler::set_target(CPUTarget target) -{ - _info.CPU = target; } -CPUInfo IScheduler::cpu_info() const +CPUInfo &IScheduler::cpu_info() { - return _info; + return _cpu_info; } unsigned int IScheduler::num_threads_hint() const -- cgit v1.2.1