From 7946e69a665436628142a1262a5ec421b9d99d29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 18 May 2024 09:58:04 +0800 Subject: [PATCH] CPU: print core count for different core types --- src/detection/cpu/cpu.h | 8 ++++++- src/detection/cpu/cpu_apple.c | 7 +++--- src/detection/cpu/cpu_bsd.c | 11 +++++---- src/detection/cpu/cpu_linux.c | 16 ++++++------- src/detection/cpu/cpu_windows.c | 19 ++++++++-------- src/modules/cpu/cpu.c | 40 ++++++++++++++++++++++++++------- 6 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/detection/cpu/cpu.h b/src/detection/cpu/cpu.h index 36755d762..982310cdb 100644 --- a/src/detection/cpu/cpu.h +++ b/src/detection/cpu/cpu.h @@ -4,6 +4,12 @@ #define FF_CPU_TEMP_UNSET (0/0.0) +typedef struct FFCPUCore +{ + uint32_t freq; + uint32_t count; +} FFCPUCore; + typedef struct FFCPUResult { FFstrbuf name; @@ -17,7 +23,7 @@ typedef struct FFCPUResult double frequencyMax; // GHz double frequencyMin; // GHz - uint8_t coreCounts[8]; // number of P cores, E cores, etc. + FFCPUCore coreTypes[8]; // number of P cores, E cores, etc. double temperature; } FFCPUResult; diff --git a/src/detection/cpu/cpu_apple.c b/src/detection/cpu/cpu_apple.c index 8c0f72827..85e06cde2 100644 --- a/src/detection/cpu/cpu_apple.c +++ b/src/detection/cpu/cpu_apple.c @@ -85,13 +85,14 @@ static const char* detectCoreCount(FFCPUResult* cpu) int nPerfLevels = ffSysctlGetInt("hw.nperflevels", 0); if (nPerfLevels <= 0) return "sysctl(hw.nperflevels) failed"; - if (nPerfLevels > (int) sizeof(cpu->coreCounts)) - nPerfLevels = (int) sizeof(cpu->coreCounts); char sysctlKey[] = "hw.perflevelN.logicalcpu"; for (int i = 0; i < nPerfLevels; ++i) { sysctlKey[strlen("hw.perflevel")] = (char) ('0' + i); - cpu->coreCounts[i] = (uint8_t) ffSysctlGetInt(sysctlKey, 0); + cpu->coreTypes[i < (int) sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0]) : i : (int) sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0]) - 1] = { + .freq = nPerfLevels - i, + .count = ffSysctlGetInt(sysctlKey, 0), + } } return NULL; } diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c index 2940c2c00..2310ac432 100644 --- a/src/detection/cpu/cpu_bsd.c +++ b/src/detection/cpu/cpu_bsd.c @@ -39,7 +39,6 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) } } - uint64_t freq = (uint64_t) -1; uint32_t ifreq = (uint32_t) -1; for (uint16_t i = 0; i < cpu->coresLogical; ++i) { @@ -57,13 +56,13 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) if (!(cpu->frequencyMin <= fmin)) cpu->frequencyMin = fmin; // Counting for NaN if (!(cpu->frequencyMax >= fmax)) cpu->frequencyMax = fmax; - if (freq != fmax) + if (cpu->coreTypes[ifreq].freq != fmax) { - freq = fmax; - ++ifreq; + if (cpu->coreTypes[ifreq].count && ifreq < sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0])) + ++ifreq; + cpu->coreTypes[ifreq].freq = fmax; } - if (__builtin_expect(ifreq < sizeof(cpu->coreCounts), true)) - cpu->coreCounts[ifreq]++; + cpu->coreTypes[ifreq].count++; } } cpu->frequencyMin /= 1000; diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 0ada1f5a4..fdcd2e3e3 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -136,11 +136,9 @@ static bool detectFrequency(FFCPUResult* cpu) FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); uint32_t baseLen = path.length; - uint64_t freq = (uint64_t) -1; - uint32_t ifreq = (uint32_t) -1; - + uint32_t ifreq = 0; struct dirent* entry; - while((entry = readdir(dir)) != NULL) + while ((entry = readdir(dir)) != NULL) { if (ffStrStartsWith(entry->d_name, "policy") && isdigit(entry->d_name[strlen("policy")])) { @@ -161,13 +159,13 @@ static bool detectFrequency(FFCPUResult* cpu) else cpu->frequencyMax = fmax; - if (fmax != freq) + if (cpu->coreTypes[ifreq].freq != fmax) { - freq = fmax; - ++ifreq; + if (cpu->coreTypes[ifreq].count && ifreq < sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0])) + ++ifreq; + cpu->coreTypes[ifreq].freq = fmax; } - if (__builtin_expect(ifreq < sizeof(cpu->coreCounts), true)) - cpu->coreCounts[ifreq] += getNumCores(&path, &buffer); + cpu->coreTypes[ifreq].count += getNumCores(&path, &buffer); } uint32_t fmin = getFrequency(&path, "/cpuinfo_min_freq", "/scaling_min_freq", &buffer); if (fmin > 0) diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index a1f09c051..2c7ce6beb 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -160,23 +160,22 @@ static const char* detectByRegistry(FFCPUResult* cpu) return NULL; } -static const char* detectCoreCounts(FFCPUResult* cpu) +static const char* detectCoreTypes(FFCPUResult* cpu) { FF_AUTO_FREE PROCESSOR_POWER_INFORMATION* pinfo = calloc(cpu->coresLogical, sizeof(PROCESSOR_POWER_INFORMATION)); if (!NT_SUCCESS(NtPowerInformation(ProcessorInformation, NULL, 0, pinfo, (ULONG) sizeof(PROCESSOR_POWER_INFORMATION) * cpu->coresLogical))) return "NtPowerInformation(ProcessorInformation, NULL, 0, pinfo, size) failed"; - uint64_t freq = (uint64_t) -1; - uint32_t ifreq = (uint32_t) -1; - for (uint32_t i = 0; i < cpu->coresLogical && pinfo[i].MhzLimit; ++i) + uint32_t ifreq = 0; + for (uint32_t i = 1; i < cpu->coresLogical && pinfo[i].MhzLimit; ++i) { - if (freq != pinfo[i].MhzLimit) + if (cpu->coreTypes[ifreq].freq != pinfo[i].MhzLimit) { - freq = pinfo[i].MhzLimit; - ++ifreq; + if (cpu->coreTypes[ifreq].count && ifreq < sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0])) + ++ifreq; + cpu->coreTypes[ifreq].freq = pinfo[i].MhzLimit; } - if (__builtin_expect(ifreq < sizeof(cpu->coreCounts), true)) - cpu->coreCounts[ifreq]++; + cpu->coreTypes[ifreq].count++; } if (cpu->frequencyBase != cpu->frequencyBase) @@ -193,7 +192,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) return error; detectSpeedByCpuid(cpu); - detectCoreCounts(cpu); + detectCoreTypes(cpu); if (cpu->frequencyMax != cpu->frequencyMax) detectMaxSpeedBySmbios(cpu); diff --git a/src/modules/cpu/cpu.c b/src/modules/cpu/cpu.c index 7c5bee4f0..c75e679be 100644 --- a/src/modules/cpu/cpu.c +++ b/src/modules/cpu/cpu.c @@ -6,7 +6,12 @@ #include "modules/cpu/cpu.h" #include "util/stringUtils.h" -#define FF_CPU_NUM_FORMAT_ARGS 8 +#define FF_CPU_NUM_FORMAT_ARGS 9 + +static int sortCores(const FFCPUCore* a, const FFCPUCore* b) +{ + return (int)b->freq - (int)a->freq; +} void ffPrintCPU(FFCPUOptions* options) { @@ -51,9 +56,9 @@ void ffPrintCPU(FFCPUOptions* options) ffStrbufAppendF(&str, " (%u)", cpu.coresOnline); double freq = cpu.frequencyMax; - if(freq != freq) + if(freq <= 0.0000001) freq = cpu.frequencyBase; - if(freq == freq) + if(freq > 0.0000001) ffStrbufAppendF(&str, " @ %.*f GHz", options->freqNdigits, freq); if(cpu.temperature == cpu.temperature) //FF_CPU_TEMP_UNSET @@ -66,6 +71,19 @@ void ffPrintCPU(FFCPUOptions* options) } else { + FF_STRBUF_AUTO_DESTROY coreTypes = ffStrbufCreate(); + uint32_t typeCount = 0; + while (cpu.coreTypes[typeCount].count != 0) typeCount++; + if (typeCount > 0) + { + qsort(cpu.coreTypes, typeCount, sizeof(cpu.coreTypes[0]), (void*) sortCores); + + for (uint32_t i = 0; i < typeCount; i++) + ffStrbufAppendF(&coreTypes, "%s%u", i == 0 ? "" : " + ", cpu.coreTypes[i].count); + } + else + ffStrbufAppendF(&coreTypes, "%u", cpu.coresOnline); + FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate(); ffTempsAppendNum(cpu.temperature, &tempStr, options->tempConfig, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(FF_CPU_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_CPU_NUM_FORMAT_ARGS, ((FFformatarg[]){ @@ -76,7 +94,8 @@ void ffPrintCPU(FFCPUOptions* options) {FF_FORMAT_ARG_TYPE_UINT16, &cpu.coresOnline}, {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu.frequencyBase}, {FF_FORMAT_ARG_TYPE_DOUBLE, &cpu.frequencyMax}, - {FF_FORMAT_ARG_TYPE_STRBUF, &tempStr} + {FF_FORMAT_ARG_TYPE_STRBUF, &tempStr}, + {FF_FORMAT_ARG_TYPE_STRBUF, &coreTypes}, })); } } @@ -180,9 +199,13 @@ void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_ yyjson_mut_obj_add_real(doc, frequency, "max", cpu.frequencyMax); yyjson_mut_obj_add_real(doc, frequency, "min", cpu.frequencyMin); - yyjson_mut_val* coreCounts = yyjson_mut_obj_add_arr(doc, obj, "coreCounts"); - for (uint32_t i = 0; i < sizeof (cpu.coreCounts) && cpu.coreCounts[i] > 0; i++) - yyjson_mut_arr_add_uint(doc, coreCounts, cpu.coreCounts[i]); + yyjson_mut_val* coreTypes = yyjson_mut_obj_add_arr(doc, obj, "coreTypes"); + for (uint32_t i = 0; i < sizeof (cpu.coreTypes) / sizeof (cpu.coreTypes[0]) && cpu.coreTypes[i].count > 0; i++) + { + yyjson_mut_val* core = yyjson_mut_arr_add_obj(doc, coreTypes); + yyjson_mut_obj_add_uint(doc, core, "count", cpu.coreTypes[i].count); + yyjson_mut_obj_add_uint(doc, core, "freq", cpu.coreTypes[i].freq); + } yyjson_mut_obj_add_real(doc, obj, "temperature", cpu.temperature); } @@ -201,7 +224,8 @@ void ffPrintCPUHelpFormat(void) "Online core count", "Base frequency", "Max frequency", - "Temperature (formatted)" + "Temperature (formatted)", + "Logical core count grouped by frequency", })); }