From 5ba2b94136177603f9e42775fb2cad53ec516fd5 Mon Sep 17 00:00:00 2001 From: liaosirui Date: Wed, 30 Oct 2024 19:14:37 +0800 Subject: [PATCH] =?UTF-8?q?cpuinfo=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/numaresources/cpuinfo.go | 202 +++++++---------------------------- 1 file changed, 37 insertions(+), 165 deletions(-) diff --git a/pkg/numaresources/cpuinfo.go b/pkg/numaresources/cpuinfo.go index 8015fc5..ba686c4 100644 --- a/pkg/numaresources/cpuinfo.go +++ b/pkg/numaresources/cpuinfo.go @@ -3,16 +3,13 @@ package numaresources import ( "context" "fmt" - "math" - "os" "os/exec" - "regexp" "sort" "strconv" "strings" "time" - "github.com/shirou/gopsutil/v3/cpu" - "k8s.io/klog/v2" + + "k8s.io/klog/v2" // "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" // "k8s.io/utils/cpuset" ) @@ -51,14 +48,14 @@ func Discover(c *CPUTotalInfo) (*CPUTopology, error) { numSockets := len(c.SocketToCPU) cpuDetails := make(CPUDetails) - // for socketId, v := range c.SocketToCPU { - // for _, socketInfo := range v { - // cpuId := socketInfo.CPUID - // tmpInfo := cpuDetails[int(cpuId)] - // tmpInfo.SocketID = int(socketId) - // cpuDetails[int(cpuId)] = tmpInfo - // } - // } + for socketId, v := range c.SocketToCPU { + for _, socketInfo := range v { + cpuId := socketInfo.CPUID + tmpInfo := cpuDetails[int(cpuId)] + tmpInfo.SocketID = int(socketId) + cpuDetails[int(cpuId)] = tmpInfo + } + } for numaNodeId, v := range c.NodeToCPU { for _, numaNodeInfo := range v { @@ -105,12 +102,6 @@ type LocalCPUInfo struct { TotalInfo CPUTotalInfo `json:"totalInfo,omitempty"` } -type numaNode struct { - numaID int32 - cpuStart int32 - cpuEnd int32 -} - type ProcessorInfo struct { // logic CPU/ processor ID CPUID int32 `json:"cpu"` @@ -123,7 +114,21 @@ type ProcessorInfo struct { } func GetLocalCPUInfo() (*LocalCPUInfo, error) { - return getCpu() + lsCPUStr, err := lsCPU("-e=CPU,NODE,SOCKET,CORE") + if err != nil { + return nil, err + } + processorInfos, err := getProcessorInfos(lsCPUStr) + if err != nil { + return nil, err + } + + totalInfo := calculateCPUTotalInfo(processorInfos) + + return &LocalCPUInfo{ + ProcessorInfos: processorInfos, + TotalInfo: totalInfo, + }, nil } const cpuCmdTimeout time.Duration = 5 * time.Second @@ -199,11 +204,11 @@ func getProcessorInfos(lsCPUStr string) ([]ProcessorInfo, error) { return processorInfos, nil } -func calculateCPUTotalInfo(processorInfos []ProcessorInfo) *CPUTotalInfo { - cpuMap := map[int32]struct{}{} - coreMap := map[int32][]ProcessorInfo{} - socketMap := map[int32][]ProcessorInfo{} - nodeMap := map[int32][]ProcessorInfo{} +func calculateCPUTotalInfo(processorInfos []ProcessorInfo) CPUTotalInfo { + cpuMap := make(map[int32]struct{}) + coreMap := make(map[int32][]ProcessorInfo) + socketMap := make(map[int32][]ProcessorInfo) + nodeMap := make(map[int32][]ProcessorInfo) for i := range processorInfos { p := processorInfos[i] @@ -213,149 +218,16 @@ func calculateCPUTotalInfo(processorInfos []ProcessorInfo) *CPUTotalInfo { nodeMap[p.NodeID] = append(nodeMap[p.NodeID], p) } - return &CPUTotalInfo{ + klog.Info("-------------------CPUTotalInfo---------------------") + klog.Infof("NumberCPUs: %v", int32(len(cpuMap))) + klog.Infof("CoreToCPU: %v", coreMap) + klog.Infof("SocketToCPU: %v", socketMap) + klog.Infof("NodeToCPU: %v", nodeMap) + + return CPUTotalInfo{ NumberCPUs: int32(len(cpuMap)), CoreToCPU: coreMap, SocketToCPU: socketMap, NodeToCPU: nodeMap, } } - -func GetNumaNodeCPUSet(c *CPUTopology, nodeid int) string { - mincpuid := math.MaxInt - maxcpuid := -1 - for cpuid, cpuinfo := range c.CPUDetails { - if cpuinfo.NUMANodeID == nodeid { - mincpuid = min(mincpuid, cpuid) - maxcpuid = max(maxcpuid, cpuid) - } - } - - result := strconv.Itoa(mincpuid) + "-" + strconv.Itoa(maxcpuid) - return result -} - -func getNodeCPU(nodeName string) (int32, int32, error) { - cpulist, err := os.ReadFile(fmt.Sprintf("/sys/devices/system/node/%s/cpulist", nodeName)) - if err != nil { - klog.Errorf("Error reading cpulist for %s: %v\n", nodeName, err) - return -1, -1, err - } - cpuRange := strings.TrimSpace(string(cpulist)) - re := regexp.MustCompile(`(\d+)-(\d+)`) - matches := re.FindStringSubmatch(cpuRange) - if len(matches) != 3 { - return -1, -1, fmt.Errorf("err cpu range format found") - } - cpuStart, err := strconv.Atoi(matches[1]) - if err != nil { - return -1, -1, err - } - cpuEnd, err := strconv.Atoi(matches[2]) - if err != nil { - return -1, -1, err - } - // klog.Errorf("CPUs: %d - %d\n", cpuStart, cpuEnd) - return int32(cpuStart), int32(cpuEnd), nil -} - -func getNumaNodes() ([]numaNode, error) { - // 读取 NUMA 节点信息 - nodes, err := os.ReadDir("/sys/devices/system/node/") - if err != nil { - klog.Errorf("Error reading NUMA nodes: %v\n", err) - return nil, err - } - - var nodeList []numaNode - for _, node := range nodes { - if strings.HasPrefix(node.Name(), "node") { - nodeIDStr := strings.TrimPrefix(node.Name(), "node") - nodeID, err := strconv.Atoi(nodeIDStr) - if err != nil { - klog.Errorf("Error reading NUMA ID: %v\n", err) - return nil, err - } - // klog.Errorf("node: %d\n", nodeID) - cpuStart, cpuEnd, err := getNodeCPU(node.Name()) - if err != nil { - klog.Errorf("Error reading NUMA cpus: %v\n", err) - return nil, err - } - nodeList = append(nodeList, numaNode{int32(nodeID), cpuStart, cpuEnd}) - } - } - klog.Infof("Total NUMA nodes: %d\n", len(nodeList)) - return nodeList, nil -} - -func getProcessorInfo(nodeList *[]numaNode, info cpu.InfoStat) (ProcessorInfo, error) { - // 获取 CPU 核心信息 - coreID, err := strconv.Atoi(info.CoreID) - if err != nil { - klog.Errorf("Error reading core ID: %v\n", err) - return ProcessorInfo{}, err - } - nodeID := -1 - for _, node := range *nodeList { - if coreID >= int(node.cpuStart) && coreID <= int(node.cpuEnd) { - nodeID = int(node.numaID) - break - } - } - return ProcessorInfo{ - CPUID: info.CPU, - CoreID: int32(coreID), - SocketID: -1, - NodeID: int32(nodeID), - }, nil -} - -func fillTotalInfo(processorList *[]ProcessorInfo) CPUTotalInfo { - coreToCPU := make(map[int32][]ProcessorInfo) - nodeToCPU := make(map[int32][]ProcessorInfo) - - for _, i := range *processorList { - coreToCPU[i.CoreID] = append(coreToCPU[i.CoreID], i) - nodeToCPU[i.NodeID] = append(nodeToCPU[i.NodeID], i) - } - - return CPUTotalInfo{ - int32(len(*processorList)), - coreToCPU, - nodeToCPU, - map[int32][]ProcessorInfo{}, - } -} -func getCpu() (*LocalCPUInfo, error) { - - // 获取 CPU 信息 - info, err := cpu.Info() - if err != nil { - klog.Errorf("Error get cpu info: %v\n", err) - return nil, err - } - - nodeList, err := getNumaNodes() - if err != nil { - klog.Errorf("Error get numa nodes: %v\n", err) - return nil, err - } - - var processorList []ProcessorInfo - for _, ci := range info { - pi, err := getProcessorInfo(&nodeList, ci) - if err != nil { - klog.Errorf("get processor info error: %v\n", err) - return nil, err - } - processorList = append(processorList, pi) - // klog.Errorf("CPU: %v\n", pi) - } - - cpuTotalInfo := fillTotalInfo(&processorList) - return &LocalCPUInfo{ - ProcessorInfos: processorList, - TotalInfo: cpuTotalInfo, - }, nil -} -- Gitee