diff --git a/util/cpu_map.cpp b/util/cpu_map.cpp index 4dd358bae8eafaadfd518ea1ddecf3670921bb58..2ccb33cc23c21db91e377afddd692acd053346ca 100644 --- a/util/cpu_map.cpp +++ b/util/cpu_map.cpp @@ -43,9 +43,11 @@ static map chipMap = {{"0x00000000481fd010", HIPA}, {"0x00000000480fd450", HIPE},}; static std::set onLineCpuIds; -static map cpuOfNumaNodeMap; static vector coreArray; +static vector> numaCoreLists; +static unordered_map cpuOfNumaNodeMap; static mutex pmuCoreListMtx; +static bool cpuNumaMapInit = false; static inline bool ReadCpuPackageId(int coreId, CpuTopology* cpuTopo) { @@ -67,7 +69,7 @@ static inline bool ReadCpuPackageId(int coreId, CpuTopology* cpuTopo) return true; } -static int GetNumaNodeCount() +static int GetNumaNodeCount() { DIR *dir = opendir(NUMA_PATH.c_str()); if (dir == nullptr) { @@ -95,56 +97,67 @@ unsigned* GetCoreList(int start) { return &coreArray[start]; } -int GetNumaCore(unsigned nodeId, unsigned **coreList) +static void InitialzeCpuOfNumaList() { - string nodeListFile = "/sys/devices/system/node/node" + to_string(nodeId) + "/cpulist"; - ifstream in(nodeListFile); - if (!in.is_open()) { - return -1; + lock_guard lock(pmuCoreListMtx); + if (cpuNumaMapInit) { + return; } - std::string cpulist; - in >> cpulist; - auto split = SplitStringByDelimiter(cpulist, '-'); - if (split.size() != 2) { - return -1; + unsigned maxNode = GetNumaNodeCount(); + numaCoreLists.resize(maxNode); + for (unsigned nodeId = 0; nodeId < maxNode; ++nodeId) { + std::string nodeListFile = "/sys/devices/system/node/node" + to_string(nodeId) + "/cpulist"; + ifstream in(nodeListFile); + if (!in.is_open()) { + continue; + } + std::string cpulist; + getline(in, cpulist); + in.close(); + vector cores; + auto rangeList = SplitStringByDelimiter(cpulist, ','); + for (const auto& range : rangeList) { + auto split = SplitStringByDelimiter(range, '-'); + if (split.size() == 1) { + auto cpu = stoi(split[0]); + cores.push_back(cpu); + cpuOfNumaNodeMap[cpu] = nodeId; + } else if (split.size() == 2) { + auto start = stoul(split[0]); + auto end = stoul(split[1]); + for (auto i = start; i <= end; ++i) { + cores.push_back(i); + cpuOfNumaNodeMap[i] = nodeId; + } + } + } + numaCoreLists[nodeId] = move(cores); } - auto start = stoi(split[0]); - auto end = stoi(split[1]); - int coreNums = end - start + 1; - if (coreNums <= 0) { + cpuNumaMapInit = true; +} + +int GetNumaCore(unsigned nodeId, unsigned **coreList) +{ + if (!cpuNumaMapInit) { + InitialzeCpuOfNumaList(); + } + + if (nodeId >= numaCoreLists.size() || numaCoreLists[nodeId].empty()) { return -1; } - *coreList = GetCoreList(start); - return coreNums; + + *coreList = numaCoreLists[nodeId].data(); + return numaCoreLists[nodeId].size(); } int GetNumaNodeOfCpu(int coreId) { - if (!cpuOfNumaNodeMap.empty()) { - if (cpuOfNumaNodeMap.find(coreId) != cpuOfNumaNodeMap.end()) { - return cpuOfNumaNodeMap[coreId]; - } else { - return -1; - } + if (!cpuNumaMapInit) { + InitialzeCpuOfNumaList(); } - unsigned maxNode = GetNumaNodeCount(); - int nodeId = -1; - for (int i = 0; i < maxNode; i++) { - unsigned *coreList = nullptr; - int numCore = GetNumaCore(i, &coreList); - if (numCore == -1) { - continue; - } - for (int j = 0; j < numCore; j++) { - int cpuId = coreList[j]; - cpuOfNumaNodeMap[cpuId] = i; - if (coreId == cpuId) { - nodeId = i; - } - } - } - return nodeId; + auto it = cpuOfNumaNodeMap.find(coreId); + return (it != cpuOfNumaNodeMap.end()) ? it->second : -1; } struct CpuTopology* GetCpuTopology(int coreId) diff --git a/util/cpu_map.h b/util/cpu_map.h index 14f2b790f372073b1bec8ce92c4bd3a0ab0157bd..0b6f8c11660022f9a825a28ca3efeb0d30336d2f 100644 --- a/util/cpu_map.h +++ b/util/cpu_map.h @@ -16,6 +16,7 @@ #define CPU_MAP_H #include #include +#include #include "pmu.h" #define MAX_CPU_NUM sysconf(_SC_NPROCESSORS_CONF)