func Init() error { var err error onceLer.Do(func() { if cpuNumCores, err = cpu.Counts(true); err != nil { err = fmt.Errorf("Unable to determine the number of CPU cores available: %v", err) return } var cpuInfo []cpu.InfoStat if cpuInfo, err = cpu.Info(); err != nil { err = fmt.Errorf("Unable to obtain CPU information: %v", err) return } for _, cpu := range cpuInfo { cpuModelName = cpu.ModelName cpuMhzPerCore = cpu.Mhz break } // Floor all of the values such that small difference don't cause the // node to fall into a unique computed node class cpuMhzPerCore = math.Floor(cpuMhzPerCore) cpuTotalTicks = math.Floor(float64(cpuNumCores) * cpuMhzPerCore) }) return err }
func (f *CPUFingerprint) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) { cpuInfo, err := cpu.Info() if err != nil { f.logger.Println("[WARN] Error reading CPU information:", err) return false, err } var numCores int32 var mhz float64 var modelName string // Assume all CPUs found have same Model. Log if not. // If CPUInfo() returns nil above, this loop is still safe for _, c := range cpuInfo { numCores += c.Cores mhz += c.Mhz if modelName != "" && modelName != c.ModelName { f.logger.Println("[WARN] Found different model names in the same CPU information. Recording last found") } modelName = c.ModelName } // Get average CPU frequency mhz /= float64(len(cpuInfo)) if mhz > 0 { node.Attributes["cpu.frequency"] = fmt.Sprintf("%.6f", mhz) f.logger.Printf("[DEBUG] fingerprint.cpu: frequency: %02.1fMHz", mhz) } if numCores <= 0 { const defaultCPUCoreCount = 1 f.logger.Printf("[DEBUG] fingerprint.cpu: unable to find core count, defaulting to %d", defaultCPUCoreCount) numCores = defaultCPUCoreCount } if numCores > 0 { node.Attributes["cpu.numcores"] = fmt.Sprintf("%d", numCores) f.logger.Printf("[DEBUG] fingerprint.cpu: core count: %d", numCores) } if mhz > 0 && numCores > 0 { tc := float64(numCores) * mhz node.Attributes["cpu.totalcompute"] = fmt.Sprintf("%.6f", tc) if node.Resources == nil { node.Resources = &structs.Resources{} } node.Resources.CPU = int(tc) } if modelName != "" { node.Attributes["cpu.modelname"] = modelName } return true, nil }
// TotalTicksAvailable calculates the total frequency available across all cores func TotalTicksAvailable() float64 { ticksLock.Lock() defer ticksLock.Unlock() if clkSpeed == 0.0 { var cpuInfo []cpu.InfoStat var err error var totalTicks float64 if cpuInfo, err = cpu.Info(); err == nil { for _, cpu := range cpuInfo { totalTicks += cpu.Mhz } clkSpeed = totalTicks } } return clkSpeed }