From b8915b1faa79a1677174c34271f6a4d155aec78f Mon Sep 17 00:00:00 2001 From: wangdongxu Date: Fri, 30 Oct 2020 19:12:38 +0800 Subject: [PATCH] use arm arch to sort cpu --- mindspore/lite/src/runtime/thread_pool.c | 187 ++++++++++++++++++++++- 1 file changed, 185 insertions(+), 2 deletions(-) diff --git a/mindspore/lite/src/runtime/thread_pool.c b/mindspore/lite/src/runtime/thread_pool.c index 61e73c4530..ce140a0042 100644 --- a/mindspore/lite/src/runtime/thread_pool.c +++ b/mindspore/lite/src/runtime/thread_pool.c @@ -140,9 +140,36 @@ static bool run_once = true; #define MAX_CPU_ID (9) #define MAX_PATH_SIZE (256) + +enum Arch { + UnKnown_Arch = 0, + Cortex_A5, + Cortex_A7, + Cortex_A8, + Cortex_A9, + Cortex_A12, + Cortex_A15, + Cortex_A17, + Cortex_A32, + Cortex_A34, + Cortex_A35, + Cortex_A53, + Cortex_A55, + Cortex_A57, + Cortex_A65, + Cortex_A72, + Cortex_A73, + Cortex_A75, + Cortex_A76, + Cortex_A77, + Cortex_A78, + Cortex_X1 +}; + typedef struct { int core_id; int max_freq; + enum Arch arch; } CpuInfo; int GetCpuCoreNum() { return (int)sysconf(_SC_NPROCESSORS_CONF); } @@ -210,6 +237,156 @@ int GetMaxFrequence(int core_id) { return maxFreq; } +int ParseCpuPart(const char *line, int start, int size) { + int cpu_part = 0; + for (int i = start; i < size && i < start + 3; i++) { + char c = line[i]; + int d; + if (c >= '0' && c <= '9') { + d = c - '0'; + } else if ((c - 'A') < 6) { + d = 10 + (c - 'A'); + } else if ((c - 'a') < 6) { + d = 10 + (c - 'a'); + } else { + LOG_ERROR("CPU part in /proc/cpuinfo is ignored due to unexpected non-hex character"); + break; + } + cpu_part = cpu_part * 16 + d; + } + return cpu_part; +} + +enum Arch GetArch(int cpu_part) { + // https://en.wikipedia.org/wiki/Comparison_of_ARMv7-A_cores + // https://en.wikipedia.org/wiki/Comparison_of_ARMv8-A_cores + switch (cpu_part) { + case 0x800: // High-performance Kryo 260 (r10p2) / Kryo 280 (r10p1) "Gold" -> Cortex-A73 + return Cortex_A73; + case 0x801: // Low-power Kryo 260 / 280 "Silver" -> Cortex-A53 + return Cortex_A53; + case 0x802: // High-performance Kryo 385 "Gold" -> Cortex-A75 + return Cortex_A75; + case 0x803: // Low-power Kryo 385 "Silver" -> Cortex-A55r0 + return Cortex_A55; + case 0x804: // High-performance Kryo 485 "Gold" / "Gold Prime" -> Cortex-A76 + return Cortex_A76; + case 0x805: // Low-performance Kryo 485 "Silver" -> Cortex-A55 + return Cortex_A55; + case 0xC05: + return Cortex_A5; + case 0xC07: + return Cortex_A7; + case 0xC08: + return Cortex_A8; + case 0xC09: + return Cortex_A9; + case 0xC0C: + return Cortex_A12; + case 0xC0D: + return Cortex_A12; + case 0xC0E: + return Cortex_A17; + case 0xC0F: + return Cortex_A15; + case 0xD01: // also Huawei Kunpeng 920 series taishan_v110 when not on android + return Cortex_A32; + case 0xD02: + return Cortex_A34; + case 0xD03: + return Cortex_A53; + case 0xD04: + return Cortex_A35; + case 0xD05: + return Cortex_A55; + case 0xD06: + return Cortex_A65; + case 0xD07: + return Cortex_A57; + case 0xD08: + return Cortex_A72; + case 0xD09: + return Cortex_A73; + case 0xD0A: + return Cortex_A75; + case 0xD0B: + return Cortex_A76; + case 0xD0D: + return Cortex_A77; + case 0xD0E: // Cortex-A76AE + return Cortex_A76; + case 0xD40: // Kirin 980 Big/Medium cores -> Cortex-A76 + return Cortex_A76; + case 0xD41: + return Cortex_A78; + case 0xD43: // Cortex-A65AE + return Cortex_A65; + case 0xD44: + return Cortex_X1; + default: + return UnKnown_Arch; + } +} + +int SetArch(CpuInfo *freq_set, int core_num) { + if (core_num <= 0) { + LOG_ERROR("core_num must be greater than 0."); + return RET_TP_ERROR; + } + FILE *fp = fopen("/proc/cpuinfo", "r"); + if (fp == NULL) { + LOG_ERROR("read /proc/cpuinfo error."); + return RET_TP_ERROR; + } + enum Arch *archs = malloc(core_num * sizeof(enum Arch)); + if (archs == NULL) { + fclose(fp); + LOG_ERROR("malloc memory for archs error."); + return RET_TP_ERROR; + } + const int max_line_size = 1024; + char line[max_line_size] = {0}; + int count = 0; + while (!feof(fp)) { + fgets(line, max_line_size, fp); + // line start with "CPU part" + if (0 == memcmp(line, "CPU part", 8)) { + // get number like 0xD03 + for (int i = 0; i < max_line_size - 4; ++i) { + if (line[i] == '0' && line[i + 1] == 'x') { + int cpu_part = ParseCpuPart(line, i + 2, max_line_size); + enum Arch arch = GetArch(cpu_part); + if (arch == UnKnown_Arch) { + LOG_ERROR("cpu's architecture is unknown."); + free(archs); + fclose(fp); + return RET_TP_ERROR; + } + count++; + if (count > core_num) { + LOG_ERROR("number of cpu_part in /proc/cpuinfo is more than core_num."); + free(archs); + fclose(fp); + return RET_TP_ERROR; + } + archs[count - 1] = arch; + } + } + } + } + if (count < core_num) { + LOG_ERROR("number of cpu_part in /proc/cpuinfo is less than core_num."); + free(archs); + fclose(fp); + return RET_TP_ERROR; + } + for (int i = 0; i < core_num; ++i) { + freq_set[i].arch = archs[i]; + } + free(archs); + return RET_TP_OK; +} + int SortCpuProcessor() { gCoreNum = GetCpuCoreNum(); if (gCoreNum <= 0) { @@ -221,11 +398,17 @@ int SortCpuProcessor() { int max_freq = GetMaxFrequence(i); freq_set[i].core_id = i; freq_set[i].max_freq = max_freq; + freq_set[i].arch = UnKnown_Arch; + } + int err_code = SetArch(freq_set, gCoreNum); + if (err_code != RET_TP_OK) { + LOG_ERROR("set arch failed."); } - // sort core id by frequency + // sort core id by frequency into descending order for (int i = 0; i < gCoreNum; ++i) { for (int j = i + 1; j < gCoreNum; ++j) { - if (freq_set[i].max_freq <= freq_set[j].max_freq) { + if (freq_set[i].max_freq < freq_set[j].max_freq || + (freq_set[i].max_freq == freq_set[j].max_freq && freq_set[i].arch <= freq_set[j].arch)) { CpuInfo temp = freq_set[i]; freq_set[i] = freq_set[j]; freq_set[j] = temp;