mirror of
https://github.com/Dr-Noob/cpufetch.git
synced 2026-03-25 16:00:39 +01:00
Compare commits
3 Commits
measure-fr
...
testk
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fc3ef4ada | ||
|
|
360562afe9 | ||
|
|
7e71cf1eb9 |
4
Makefile
4
Makefile
@@ -7,8 +7,8 @@ PREFIX ?= /usr
|
|||||||
|
|
||||||
SRC_COMMON=src/common/
|
SRC_COMMON=src/common/
|
||||||
|
|
||||||
COMMON_SRC = $(SRC_COMMON)main.c $(SRC_COMMON)cpu.c $(SRC_COMMON)udev.c $(SRC_COMMON)printer.c $(SRC_COMMON)args.c $(SRC_COMMON)global.c $(SRC_COMMON)freq.c
|
COMMON_SRC = $(SRC_COMMON)main.c $(SRC_COMMON)cpu.c $(SRC_COMMON)udev.c $(SRC_COMMON)printer.c $(SRC_COMMON)args.c $(SRC_COMMON)global.c
|
||||||
COMMON_HDR = $(SRC_COMMON)ascii.h $(SRC_COMMON)cpu.h $(SRC_COMMON)udev.h $(SRC_COMMON)printer.h $(SRC_COMMON)args.h $(SRC_COMMON)global.h $(SRC_COMMON)freq.h
|
COMMON_HDR = $(SRC_COMMON)ascii.h $(SRC_COMMON)cpu.h $(SRC_COMMON)udev.h $(SRC_COMMON)printer.h $(SRC_COMMON)args.h $(SRC_COMMON)global.h
|
||||||
|
|
||||||
ifneq ($(OS),Windows_NT)
|
ifneq ($(OS),Windows_NT)
|
||||||
GIT_VERSION := "$(shell git describe --abbrev=4 --dirty --always --tags)"
|
GIT_VERSION := "$(shell git describe --abbrev=4 --dirty --always --tags)"
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
#include "../common/global.h"
|
#include "../common/global.h"
|
||||||
#include "../common/soc.h"
|
#include "../common/soc.h"
|
||||||
#include "../common/freq.h"
|
|
||||||
#include "udev.h"
|
#include "udev.h"
|
||||||
#include "midr.h"
|
#include "midr.h"
|
||||||
#include "uarch.h"
|
#include "uarch.h"
|
||||||
@@ -42,12 +41,6 @@ struct frequency* get_frequency_info(uint32_t core) {
|
|||||||
|
|
||||||
freq->base = UNKNOWN_DATA;
|
freq->base = UNKNOWN_DATA;
|
||||||
freq->max = get_max_freq_from_file(core);
|
freq->max = get_max_freq_from_file(core);
|
||||||
#ifdef __linux__
|
|
||||||
if (freq->max == UNKNOWN_DATA) {
|
|
||||||
printWarn("Unable to find max frequency from udev, measuring CPU frequency");
|
|
||||||
freq->max = measure_max_frequency(core);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return freq;
|
return freq;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,154 +0,0 @@
|
|||||||
#ifdef __linux__
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <asm/unistd.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <linux/perf_event.h>
|
|
||||||
|
|
||||||
#include "global.h"
|
|
||||||
|
|
||||||
static long
|
|
||||||
perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
|
|
||||||
int cpu, int group_fd, unsigned long flags) {
|
|
||||||
int ret;
|
|
||||||
ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
|
|
||||||
group_fd, flags);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define INSERT_ASM_ONCE __asm volatile("nop");
|
|
||||||
#define INSERT_ASM_10_TIMES \
|
|
||||||
INSERT_ASM_ONCE \
|
|
||||||
INSERT_ASM_ONCE \
|
|
||||||
INSERT_ASM_ONCE \
|
|
||||||
INSERT_ASM_ONCE \
|
|
||||||
INSERT_ASM_ONCE \
|
|
||||||
INSERT_ASM_ONCE \
|
|
||||||
INSERT_ASM_ONCE \
|
|
||||||
INSERT_ASM_ONCE \
|
|
||||||
INSERT_ASM_ONCE \
|
|
||||||
INSERT_ASM_ONCE \
|
|
||||||
|
|
||||||
#define INSERT_ASM_100_TIMES \
|
|
||||||
INSERT_ASM_10_TIMES \
|
|
||||||
INSERT_ASM_10_TIMES \
|
|
||||||
INSERT_ASM_10_TIMES \
|
|
||||||
INSERT_ASM_10_TIMES \
|
|
||||||
INSERT_ASM_10_TIMES \
|
|
||||||
INSERT_ASM_10_TIMES \
|
|
||||||
INSERT_ASM_10_TIMES \
|
|
||||||
INSERT_ASM_10_TIMES \
|
|
||||||
INSERT_ASM_10_TIMES \
|
|
||||||
INSERT_ASM_10_TIMES
|
|
||||||
|
|
||||||
#define INSERT_ASM_1000_TIMES \
|
|
||||||
INSERT_ASM_100_TIMES \
|
|
||||||
INSERT_ASM_100_TIMES \
|
|
||||||
INSERT_ASM_100_TIMES \
|
|
||||||
INSERT_ASM_100_TIMES \
|
|
||||||
INSERT_ASM_100_TIMES \
|
|
||||||
INSERT_ASM_100_TIMES \
|
|
||||||
INSERT_ASM_100_TIMES \
|
|
||||||
INSERT_ASM_100_TIMES \
|
|
||||||
INSERT_ASM_100_TIMES \
|
|
||||||
INSERT_ASM_100_TIMES \
|
|
||||||
|
|
||||||
void nop_function(uint64_t iters) {
|
|
||||||
for (uint64_t i = 0; i < iters; i++) {
|
|
||||||
INSERT_ASM_1000_TIMES
|
|
||||||
INSERT_ASM_1000_TIMES
|
|
||||||
INSERT_ASM_1000_TIMES
|
|
||||||
INSERT_ASM_1000_TIMES
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Differences between x86 measure_frequency this measure_max_frequency:
|
|
||||||
// - measure_frequency employs all cores simultaneously wherease
|
|
||||||
// measure_max_frequency only employs 1.
|
|
||||||
// - measure_frequency runs the computation and checks /proc/cpuinfo whereas
|
|
||||||
// measure_max_frequency does not rely on /proc/cpuinfo and simply
|
|
||||||
// counts cpu cycles to measure frequency.
|
|
||||||
// - measure_frequency uses actual computation while measuring the frequency
|
|
||||||
// whereas measure_max_frequency uses nop instructions. This makes the former
|
|
||||||
// x86 dependant whereas the latter is architecture independant.
|
|
||||||
int64_t measure_max_frequency(uint32_t core) {
|
|
||||||
if (!bind_to_cpu(core)) {
|
|
||||||
printErr("Failed binding the process to CPU %d", core);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
clockid_t clock = CLOCK_PROCESS_CPUTIME_ID;
|
|
||||||
|
|
||||||
struct perf_event_attr pe;
|
|
||||||
uint64_t instructions;
|
|
||||||
int fd;
|
|
||||||
int pid = 0;
|
|
||||||
|
|
||||||
memset(&pe, 0, sizeof(struct perf_event_attr));
|
|
||||||
pe.type = PERF_TYPE_HARDWARE;
|
|
||||||
pe.size = sizeof(struct perf_event_attr);
|
|
||||||
pe.config = PERF_COUNT_HW_CPU_CYCLES;
|
|
||||||
pe.disabled = 1;
|
|
||||||
pe.exclude_kernel = 1;
|
|
||||||
pe.exclude_hv = 1;
|
|
||||||
|
|
||||||
fd = perf_event_open(&pe, pid, core, -1, 0);
|
|
||||||
if (fd == -1) {
|
|
||||||
perror("perf_event_open");
|
|
||||||
if (errno == EPERM || errno == EACCES) {
|
|
||||||
printf("You may not have permission to collect stats.\n");
|
|
||||||
printf("Consider tweaking /proc/sys/kernel/perf_event_paranoid or running as root.\n");
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* frequency_banner = "cpufetch is measuring the max frequency...";
|
|
||||||
printf("%s", frequency_banner);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
uint64_t iters = 10000000;
|
|
||||||
struct timespec start, end;
|
|
||||||
if (clock_gettime(clock, &start) == -1) {
|
|
||||||
perror("clock_gettime");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(ioctl(fd, PERF_EVENT_IOC_RESET, 0) == -1) {
|
|
||||||
perror("ioctl");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(ioctl(fd, PERF_EVENT_IOC_ENABLE, 0) == -1) {
|
|
||||||
perror("ioctl");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
nop_function(iters);
|
|
||||||
|
|
||||||
read(fd, &instructions, sizeof(uint64_t));
|
|
||||||
if(ioctl(fd, PERF_EVENT_IOC_DISABLE, 0) == -1) {
|
|
||||||
perror("ioctl");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (clock_gettime(clock, &end) == -1) {
|
|
||||||
perror("clock_gettime");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t nsecs = (end.tv_sec*1e9 + end.tv_nsec) - (start.tv_sec*1e9 + start.tv_nsec);
|
|
||||||
uint64_t usecs = nsecs/1000;
|
|
||||||
double frequency = instructions/((double)usecs);
|
|
||||||
|
|
||||||
printf("\r%*c\r", (int) strlen(frequency_banner), ' ');
|
|
||||||
|
|
||||||
// Discard last digit in the frequency, which should help providing
|
|
||||||
// more reliable and predictable values.
|
|
||||||
return (((int) frequency + 5)/10) * 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // #ifdef __linux__
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#ifndef __COMMON_FREQ__
|
|
||||||
#define __COMMON_FREQ__
|
|
||||||
|
|
||||||
int64_t measure_max_frequency(uint32_t core);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,14 +1,3 @@
|
|||||||
#ifdef _WIN32
|
|
||||||
#define NOMINMAX
|
|
||||||
#include <windows.h>
|
|
||||||
#elif defined __linux__
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <sched.h>
|
|
||||||
#elif defined __FreeBSD__
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/cpuset.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -32,7 +21,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ARCH_X86
|
#ifdef ARCH_X86
|
||||||
static const char* ARCH_STR = "x86 / x86_64 build";
|
static const char* ARCH_STR = "x86_64 build";
|
||||||
#include "../x86/cpuid.h"
|
#include "../x86/cpuid.h"
|
||||||
#elif ARCH_PPC
|
#elif ARCH_PPC
|
||||||
static const char* ARCH_STR = "PowerPC build";
|
static const char* ARCH_STR = "PowerPC build";
|
||||||
@@ -210,34 +199,6 @@ void* erealloc(void *ptr, size_t size) {
|
|||||||
return newptr;
|
return newptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __APPLE__
|
|
||||||
bool bind_to_cpu(int cpu_id) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
HANDLE process = GetCurrentProcess();
|
|
||||||
DWORD_PTR processAffinityMask = 1 << cpu_id;
|
|
||||||
return SetProcessAffinityMask(process, processAffinityMask);
|
|
||||||
#elif defined __linux__
|
|
||||||
cpu_set_t currentCPU;
|
|
||||||
CPU_ZERO(¤tCPU);
|
|
||||||
CPU_SET(cpu_id, ¤tCPU);
|
|
||||||
if (sched_setaffinity (0, sizeof(currentCPU), ¤tCPU) == -1) {
|
|
||||||
printWarn("sched_setaffinity: %s", strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
#elif defined __FreeBSD__
|
|
||||||
cpuset_t currentCPU;
|
|
||||||
CPU_ZERO(¤tCPU);
|
|
||||||
CPU_SET(cpu_id, ¤tCPU);
|
|
||||||
if(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset_t), ¤tCPU) == -1) {
|
|
||||||
printWarn("cpuset_setaffinity: %s", strerror(errno));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void print_version(FILE *restrict stream) {
|
void print_version(FILE *restrict stream) {
|
||||||
#ifdef GIT_FULL_VERSION
|
#ifdef GIT_FULL_VERSION
|
||||||
fprintf(stream, "cpufetch %s (%s %s)\n", GIT_FULL_VERSION, OS_STR, ARCH_STR);
|
fprintf(stream, "cpufetch %s (%s %s)\n", GIT_FULL_VERSION, OS_STR, ARCH_STR);
|
||||||
|
|||||||
@@ -19,9 +19,6 @@ char *strremove(char *str, const char *sub);
|
|||||||
void* emalloc(size_t size);
|
void* emalloc(size_t size);
|
||||||
void* ecalloc(size_t nmemb, size_t size);
|
void* ecalloc(size_t nmemb, size_t size);
|
||||||
void* erealloc(void *ptr, size_t size);
|
void* erealloc(void *ptr, size_t size);
|
||||||
#ifndef __APPLE__
|
|
||||||
bool bind_to_cpu(int cpu_id);
|
|
||||||
#endif
|
|
||||||
void print_version(FILE *restrict stream);
|
void print_version(FILE *restrict stream);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ enum {
|
|||||||
ATTRIBUTE_NCORES,
|
ATTRIBUTE_NCORES,
|
||||||
ATTRIBUTE_NCORES_DUAL,
|
ATTRIBUTE_NCORES_DUAL,
|
||||||
#ifdef ARCH_X86
|
#ifdef ARCH_X86
|
||||||
ATTRIBUTE_SSE,
|
|
||||||
ATTRIBUTE_AVX,
|
ATTRIBUTE_AVX,
|
||||||
ATTRIBUTE_FMA,
|
ATTRIBUTE_FMA,
|
||||||
#elif ARCH_PPC
|
#elif ARCH_PPC
|
||||||
@@ -97,7 +96,6 @@ static const char* ATTRIBUTE_FIELDS [] = {
|
|||||||
"Cores:",
|
"Cores:",
|
||||||
"Cores (Total):",
|
"Cores (Total):",
|
||||||
#ifdef ARCH_X86
|
#ifdef ARCH_X86
|
||||||
"SSE:",
|
|
||||||
"AVX:",
|
"AVX:",
|
||||||
"FMA:",
|
"FMA:",
|
||||||
#elif ARCH_PPC
|
#elif ARCH_PPC
|
||||||
@@ -133,7 +131,6 @@ static const char* ATTRIBUTE_FIELDS_SHORT [] = {
|
|||||||
"Cores:",
|
"Cores:",
|
||||||
"Cores (Total):",
|
"Cores (Total):",
|
||||||
#ifdef ARCH_X86
|
#ifdef ARCH_X86
|
||||||
"SSE:",
|
|
||||||
"AVX:",
|
"AVX:",
|
||||||
"FMA:",
|
"FMA:",
|
||||||
#elif ARCH_PPC
|
#elif ARCH_PPC
|
||||||
@@ -339,13 +336,6 @@ struct ascii_logo* choose_ascii_art_aux(struct ascii_logo* logo_long, struct asc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://no-color.org/
|
|
||||||
bool is_color_enabled(void) {
|
|
||||||
const char *var_name = "NO_COLOR";
|
|
||||||
char *no_color = getenv(var_name);
|
|
||||||
return no_color == NULL || no_color[0] == '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* term, int lf) {
|
void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* term, int lf) {
|
||||||
// 1. Choose logo
|
// 1. Choose logo
|
||||||
#ifdef ARCH_X86
|
#ifdef ARCH_X86
|
||||||
@@ -404,9 +394,6 @@ void choose_ascii_art(struct ascii* art, struct color** cs, struct terminal* ter
|
|||||||
|
|
||||||
// 2. Choose colors
|
// 2. Choose colors
|
||||||
struct ascii_logo* logo = art->art;
|
struct ascii_logo* logo = art->art;
|
||||||
bool color = is_color_enabled();
|
|
||||||
if (!color)
|
|
||||||
art->style = STYLE_LEGACY;
|
|
||||||
|
|
||||||
switch(art->style) {
|
switch(art->style) {
|
||||||
case STYLE_LEGACY:
|
case STYLE_LEGACY:
|
||||||
@@ -592,7 +579,6 @@ bool print_cpufetch_x86(struct cpuInfo* cpu, STYLE s, struct color** cs, struct
|
|||||||
for(int i = 0; i < cpu->num_cpus; ptr = ptr->next_cpu, i++) {
|
for(int i = 0; i < cpu->num_cpus; ptr = ptr->next_cpu, i++) {
|
||||||
char* max_frequency = get_str_freq(ptr->freq);
|
char* max_frequency = get_str_freq(ptr->freq);
|
||||||
char* avx = get_str_avx(ptr);
|
char* avx = get_str_avx(ptr);
|
||||||
char* sse = get_str_sse(ptr);
|
|
||||||
char* fma = get_str_fma(ptr);
|
char* fma = get_str_fma(ptr);
|
||||||
char* cpu_num = emalloc(sizeof(char) * 9);
|
char* cpu_num = emalloc(sizeof(char) * 9);
|
||||||
|
|
||||||
@@ -627,17 +613,8 @@ bool print_cpufetch_x86(struct cpuInfo* cpu, STYLE s, struct color** cs, struct
|
|||||||
setAttribute(art, ATTRIBUTE_NCORES, n_cores);
|
setAttribute(art, ATTRIBUTE_NCORES, n_cores);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the most modern vector instructions.
|
|
||||||
// If AVX is supported show it, otherwise show SSE
|
|
||||||
if (strcmp(avx, "No") == 0) {
|
|
||||||
setAttribute(art, ATTRIBUTE_SSE, sse);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setAttribute(art, ATTRIBUTE_AVX, avx);
|
setAttribute(art, ATTRIBUTE_AVX, avx);
|
||||||
setAttribute(art, ATTRIBUTE_FMA, fma);
|
setAttribute(art, ATTRIBUTE_FMA, fma);
|
||||||
}
|
|
||||||
|
|
||||||
if(l1i != NULL) setAttribute(art, ATTRIBUTE_L1i, l1i);
|
if(l1i != NULL) setAttribute(art, ATTRIBUTE_L1i, l1i);
|
||||||
if(l1d != NULL) setAttribute(art, ATTRIBUTE_L1d, l1d);
|
if(l1d != NULL) setAttribute(art, ATTRIBUTE_L1d, l1d);
|
||||||
if(l2 != NULL) setAttribute(art, ATTRIBUTE_L2, l2);
|
if(l2 != NULL) setAttribute(art, ATTRIBUTE_L2, l2);
|
||||||
|
|||||||
@@ -280,6 +280,9 @@ char* get_str_process(struct cpuInfo* cpu) {
|
|||||||
if(process == UNK) {
|
if(process == UNK) {
|
||||||
snprintf(str, strlen(STRING_UNKNOWN)+1, STRING_UNKNOWN);
|
snprintf(str, strlen(STRING_UNKNOWN)+1, STRING_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
else if(process > 100) {
|
||||||
|
sprintf(str, "%.2fum", (double)process/100);
|
||||||
|
}
|
||||||
else if(process > 0){
|
else if(process > 0){
|
||||||
sprintf(str, "%dnm", process);
|
sprintf(str, "%dnm", process);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,34 @@ uint32_t get_apic_id(bool x2apic_id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __APPLE__
|
||||||
|
bool bind_to_cpu(int cpu_id) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
HANDLE process = GetCurrentProcess();
|
||||||
|
DWORD_PTR processAffinityMask = 1 << cpu_id;
|
||||||
|
return SetProcessAffinityMask(process, processAffinityMask);
|
||||||
|
#elif defined __linux__
|
||||||
|
cpu_set_t currentCPU;
|
||||||
|
CPU_ZERO(¤tCPU);
|
||||||
|
CPU_SET(cpu_id, ¤tCPU);
|
||||||
|
if (sched_setaffinity (0, sizeof(currentCPU), ¤tCPU) == -1) {
|
||||||
|
printWarn("sched_setaffinity: %s", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
#elif defined __FreeBSD__
|
||||||
|
cpuset_t currentCPU;
|
||||||
|
CPU_ZERO(¤tCPU);
|
||||||
|
CPU_SET(cpu_id, ¤tCPU);
|
||||||
|
if(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset_t), ¤tCPU) == -1) {
|
||||||
|
printWarn("cpuset_setaffinity: %s", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
int get_total_cores_module(int total_cores, int module) {
|
int get_total_cores_module(int total_cores, int module) {
|
||||||
int total_modules = 2;
|
int total_modules = 2;
|
||||||
@@ -369,11 +397,6 @@ bool fill_apic_ids(uint32_t* apic_ids, int first_core, int n, bool x2apic_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo) {
|
bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo) {
|
||||||
if (topo->cach == NULL) {
|
|
||||||
printWarn("get_topology_from_apic: cach is NULL");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t apic_id;
|
uint32_t apic_id;
|
||||||
uint32_t* apic_ids = emalloc(sizeof(uint32_t) * topo->total_cores_module);
|
uint32_t* apic_ids = emalloc(sizeof(uint32_t) * topo->total_cores_module);
|
||||||
uint32_t* apic_pkg = emalloc(sizeof(uint32_t) * topo->total_cores_module);
|
uint32_t* apic_pkg = emalloc(sizeof(uint32_t) * topo->total_cores_module);
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ struct apic {
|
|||||||
bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo);
|
bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo);
|
||||||
uint32_t is_smt_enabled_amd(struct topology* topo);
|
uint32_t is_smt_enabled_amd(struct topology* topo);
|
||||||
|
|
||||||
|
#ifndef __APPLE__
|
||||||
|
bool bind_to_cpu(int cpu_id);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
int get_total_cores_module(int total_cores, int module);
|
int get_total_cores_module(int total_cores, int module);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,10 +6,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
#include "../common/freq.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -220,7 +216,7 @@ int64_t get_peak_performance(struct cpuInfo* cpu, bool accurate_pp) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//First, check we have consistent data
|
//First, check we have consistent data
|
||||||
if(freq == UNKNOWN_DATA || topo == NULL || topo->logical_cores == UNKNOWN_DATA) {
|
if(freq == UNKNOWN_DATA || topo->logical_cores == UNKNOWN_DATA) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,7 +449,7 @@ struct cpuInfo* get_cpu_info(void) {
|
|||||||
cpu->cach = NULL;
|
cpu->cach = NULL;
|
||||||
cpu->feat = NULL;
|
cpu->feat = NULL;
|
||||||
|
|
||||||
cpu->num_cpus = 1;
|
uint32_t modules = 1;
|
||||||
uint32_t eax = 0;
|
uint32_t eax = 0;
|
||||||
uint32_t ebx = 0;
|
uint32_t ebx = 0;
|
||||||
uint32_t ecx = 0;
|
uint32_t ecx = 0;
|
||||||
@@ -490,8 +486,9 @@ struct cpuInfo* get_cpu_info(void) {
|
|||||||
cpu->cpu_name = get_str_cpu_name_internal();
|
cpu->cpu_name = get_str_cpu_name_internal();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cpu->cpu_name = NULL;
|
cpu->cpu_name = emalloc(sizeof(char) * (strlen(STRING_UNKNOWN) + 1));
|
||||||
printWarn("Can't read CPU name from cpuid (needed extended level is 0x%.8X, max is 0x%.8X)", 0x80000004, cpu->maxExtendedLevels);
|
strcpy(cpu->cpu_name, STRING_UNKNOWN);
|
||||||
|
printWarn("Can't read cpu name from cpuid (needed extended level is 0x%.8X, max is 0x%.8X)", 0x80000004, cpu->maxExtendedLevels);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu->topology_extensions = false;
|
cpu->topology_extensions = false;
|
||||||
@@ -509,12 +506,12 @@ struct cpuInfo* get_cpu_info(void) {
|
|||||||
cpu->hybrid_flag = (edx >> 15) & 0x1;
|
cpu->hybrid_flag = (edx >> 15) & 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cpu->hybrid_flag) cpu->num_cpus = 2;
|
if(cpu->hybrid_flag) modules = 2;
|
||||||
|
|
||||||
struct cpuInfo* ptr = cpu;
|
struct cpuInfo* ptr = cpu;
|
||||||
for(uint32_t i=0; i < cpu->num_cpus; i++) {
|
for(uint32_t i=0; i < modules; i++) {
|
||||||
int32_t first_core;
|
int32_t first_core;
|
||||||
set_cpu_module(i, cpu->num_cpus, &first_core);
|
set_cpu_module(i, modules, &first_core);
|
||||||
|
|
||||||
if(i > 0) {
|
if(i > 0) {
|
||||||
ptr->next_cpu = emalloc(sizeof(struct cpuInfo));
|
ptr->next_cpu = emalloc(sizeof(struct cpuInfo));
|
||||||
@@ -541,15 +538,14 @@ struct cpuInfo* get_cpu_info(void) {
|
|||||||
ptr->first_core_id = first_core;
|
ptr->first_core_id = first_core;
|
||||||
ptr->feat = get_features_info(ptr);
|
ptr->feat = get_features_info(ptr);
|
||||||
|
|
||||||
|
// If any field of the struct is NULL,
|
||||||
|
// return inmideately, as further functions
|
||||||
|
// require valid fields (cach, topo, etc)
|
||||||
ptr->arch = get_cpu_uarch(ptr);
|
ptr->arch = get_cpu_uarch(ptr);
|
||||||
ptr->freq = get_frequency_info(ptr);
|
ptr->freq = get_frequency_info(ptr);
|
||||||
|
|
||||||
if (cpu->cpu_name == NULL && ptr == cpu) {
|
|
||||||
// If we couldnt read CPU name from cpuid, infer it now
|
|
||||||
cpu->cpu_name = infer_cpu_name_from_uarch(cpu->arch);
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr->cach = get_cache_info(ptr);
|
ptr->cach = get_cache_info(ptr);
|
||||||
|
if(ptr->cach == NULL) return cpu;
|
||||||
|
|
||||||
if(cpu->hybrid_flag) {
|
if(cpu->hybrid_flag) {
|
||||||
ptr->topo = get_topology_info(ptr, ptr->cach, i);
|
ptr->topo = get_topology_info(ptr, ptr->cach, i);
|
||||||
@@ -557,23 +553,16 @@ struct cpuInfo* get_cpu_info(void) {
|
|||||||
else {
|
else {
|
||||||
ptr->topo = get_topology_info(ptr, ptr->cach, -1);
|
ptr->topo = get_topology_info(ptr, ptr->cach, -1);
|
||||||
}
|
}
|
||||||
|
if(cpu->topo == NULL) return cpu;
|
||||||
// If topo is NULL, return early, as get_peak_performance
|
|
||||||
// requries non-NULL topology.
|
|
||||||
if(ptr->topo == NULL) return cpu;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpu->num_cpus = modules;
|
||||||
cpu->peak_performance = get_peak_performance(cpu, accurate_pp());
|
cpu->peak_performance = get_peak_performance(cpu, accurate_pp());
|
||||||
|
|
||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_cache_topology_amd(struct cpuInfo* cpu, struct topology* topo) {
|
bool get_cache_topology_amd(struct cpuInfo* cpu, struct topology* topo) {
|
||||||
if (topo->cach == NULL) {
|
|
||||||
printWarn("get_cache_topology_amd: cach is NULL");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cpu->maxExtendedLevels >= 0x8000001D && cpu->topology_extensions) {
|
if(cpu->maxExtendedLevels >= 0x8000001D && cpu->topology_extensions) {
|
||||||
uint32_t i, eax, ebx, ecx, edx, num_sharing_cache, cache_type, cache_level;
|
uint32_t i, eax, ebx, ecx, edx, num_sharing_cache, cache_type, cache_level;
|
||||||
|
|
||||||
@@ -649,12 +638,10 @@ bool get_cache_topology_amd(struct cpuInfo* cpu, struct topology* topo) {
|
|||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
void get_topology_from_udev(struct topology* topo) {
|
void get_topology_from_udev(struct topology* topo) {
|
||||||
topo->total_cores = get_ncores_from_cpuinfo();
|
|
||||||
// TODO: To be improved in the future
|
// TODO: To be improved in the future
|
||||||
// Conservative setting as we only know the total
|
topo->total_cores = get_ncores_from_cpuinfo();
|
||||||
// number of cores.
|
topo->logical_cores = topo->total_cores;
|
||||||
topo->logical_cores = UNKNOWN_DATA;
|
topo->physical_cores = topo->total_cores;
|
||||||
topo->physical_cores = UNKNOWN_DATA;
|
|
||||||
topo->smt_available = 1;
|
topo->smt_available = 1;
|
||||||
topo->smt_supported = 1;
|
topo->smt_supported = 1;
|
||||||
topo->sockets = 1;
|
topo->sockets = 1;
|
||||||
@@ -718,8 +705,8 @@ struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach, int
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printWarn("Can't read topology information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x00000001, cpu->maxLevels);
|
printWarn("Can't read topology information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x00000001, cpu->maxLevels);
|
||||||
topo->physical_cores = UNKNOWN_DATA;
|
topo->physical_cores = 1;
|
||||||
topo->logical_cores = UNKNOWN_DATA;
|
topo->logical_cores = 1;
|
||||||
topo->smt_available = 1;
|
topo->smt_available = 1;
|
||||||
topo->smt_supported = 1;
|
topo->smt_supported = 1;
|
||||||
}
|
}
|
||||||
@@ -969,14 +956,6 @@ struct frequency* get_frequency_info(struct cpuInfo* cpu) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
if (freq->max == UNKNOWN_DATA) {
|
|
||||||
printWarn("All previous methods failed, measuring CPU frequency");
|
|
||||||
// TODO: Support hybrid architectures
|
|
||||||
freq->max = measure_max_frequency(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return freq;
|
return freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,5 @@
|
|||||||
#define LOOP_ITERS 100000000
|
#define LOOP_ITERS 100000000
|
||||||
|
|
||||||
int64_t measure_frequency(struct cpuInfo* cpu);
|
int64_t measure_frequency(struct cpuInfo* cpu);
|
||||||
void nop_function_x86(uint64_t iters);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -48,9 +48,7 @@ enum {
|
|||||||
UARCH_UNKNOWN,
|
UARCH_UNKNOWN,
|
||||||
// INTEL //
|
// INTEL //
|
||||||
UARCH_P5,
|
UARCH_P5,
|
||||||
UARCH_P5_MMX,
|
UARCH_P6,
|
||||||
UARCH_P6_PENTIUM_II,
|
|
||||||
UARCH_P6_PENTIUM_III,
|
|
||||||
UARCH_DOTHAN,
|
UARCH_DOTHAN,
|
||||||
UARCH_YONAH,
|
UARCH_YONAH,
|
||||||
UARCH_MEROM,
|
UARCH_MEROM,
|
||||||
@@ -146,31 +144,31 @@ struct uarch* get_uarch_from_cpuid_intel(uint32_t ef, uint32_t f, uint32_t em, u
|
|||||||
// EM: Extended Model //
|
// EM: Extended Model //
|
||||||
// M: Model //
|
// M: Model //
|
||||||
// S: Stepping //
|
// S: Stepping //
|
||||||
// ------------------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------------- //
|
||||||
// EF F EM M S //
|
// EF F EM M S //
|
||||||
UARCH_START
|
UARCH_START
|
||||||
CHECK_UARCH(arch, 0, 5, 0, 0, NA, "P5", UARCH_P5, 800)
|
CHECK_UARCH(arch, 0, 5, 0, 0, NA, "P5", UARCH_P5, 800)
|
||||||
CHECK_UARCH(arch, 0, 5, 0, 1, NA, "P5", UARCH_P5, 800)
|
CHECK_UARCH(arch, 0, 5, 0, 1, NA, "P5", UARCH_P5, 800)
|
||||||
CHECK_UARCH(arch, 0, 5, 0, 2, NA, "P5", UARCH_P5, UNK)
|
CHECK_UARCH(arch, 0, 5, 0, 2, NA, "P5", UARCH_P5, UNK)
|
||||||
CHECK_UARCH(arch, 0, 5, 0, 3, NA, "P5", UARCH_P5, 600)
|
CHECK_UARCH(arch, 0, 5, 0, 3, NA, "P5", UARCH_P5, 600)
|
||||||
CHECK_UARCH(arch, 0, 5, 0, 4, NA, "P5 (MMX)", UARCH_P5_MMX, UNK)
|
CHECK_UARCH(arch, 0, 5, 0, 4, NA, "P5 MMX", UARCH_P5, UNK)
|
||||||
CHECK_UARCH(arch, 0, 5, 0, 7, NA, "P5 (MMX)", UARCH_P5_MMX, UNK)
|
CHECK_UARCH(arch, 0, 5, 0, 7, NA, "P5 MMX", UARCH_P5, UNK)
|
||||||
CHECK_UARCH(arch, 0, 5, 0, 8, NA, "P5 (MMX)", UARCH_P5_MMX, 250)
|
CHECK_UARCH(arch, 0, 5, 0, 8, NA, "P5 MMX", UARCH_P5, 250)
|
||||||
CHECK_UARCH(arch, 0, 5, 0, 9, 0, "Lakemont", UARCH_LAKEMONT, 32)
|
CHECK_UARCH(arch, 0, 5, 0, 9, 0, "Lakemont", UARCH_LAKEMONT, 32)
|
||||||
CHECK_UARCH(arch, 0, 5, 0, 9, NA, "P5 (MMX)", UARCH_P5_MMX, UNK)
|
CHECK_UARCH(arch, 0, 5, 0, 9, NA, "P5 MMX", UARCH_P5, UNK)
|
||||||
CHECK_UARCH(arch, 0, 5, 0, 10, 0, "Lakemont", UARCH_LAKEMONT, 32)
|
CHECK_UARCH(arch, 0, 5, 0, 10, 0, "Lakemont", UARCH_LAKEMONT, 32)
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 0, NA, "P6 (Pentium II)", UARCH_P6_PENTIUM_II, UNK)
|
CHECK_UARCH(arch, 0, 6, 0, 0, NA, "P6 Pentium II", UARCH_P6, UNK)
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 1, NA, "P6 (Pentium II)", UARCH_P6_PENTIUM_II, UNK) // process depends on core
|
CHECK_UARCH(arch, 0, 6, 0, 1, NA, "P6 Pentium II", UARCH_P6, UNK) // process depends on core
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 2, NA, "P6 (Pentium II)", UARCH_P6_PENTIUM_II, UNK)
|
CHECK_UARCH(arch, 0, 6, 0, 2, NA, "P6 Pentium II", UARCH_P6, UNK)
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 3, NA, "P6 (Klamath)", UARCH_P6_PENTIUM_II, 350) // http://instlatx64.atw.hu.
|
CHECK_UARCH(arch, 0, 6, 0, 3, NA, "P6 Pentium II", UARCH_P6, 350)
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 4, NA, "P6 (Pentium II)", UARCH_P6_PENTIUM_II, UNK)
|
CHECK_UARCH(arch, 0, 6, 0, 4, NA, "P6 Pentium II", UARCH_P6, UNK)
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 5, NA, "P6 (Deschutes)", UARCH_P6_PENTIUM_II, 250) // http://instlatx64.atw.hu.
|
CHECK_UARCH(arch, 0, 6, 0, 5, NA, "P6 Pentium II", UARCH_P6, 250)
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 6, NA, "P6 (Dixon)", UARCH_P6_PENTIUM_II, UNK) // http://instlatx64.atw.hu.
|
CHECK_UARCH(arch, 0, 6, 0, 6, NA, "P6 Pentium II", UARCH_P6, UNK)
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 7, NA, "P6 (Katmai)", UARCH_P6_PENTIUM_III, 250) // Core names from: https://en.wikichip.org/wiki/intel/cpuid. NOTE: Xeon core names are different! https://www.techpowerup.com/cpu-specs/?generation=Intel+Pentium+III+Xeon
|
CHECK_UARCH(arch, 0, 6, 0, 7, NA, "P6 Pentium III", UARCH_P6, 250)
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 8, NA, "P6 (Coppermine)", UARCH_P6_PENTIUM_III, 180) // Also: https://en.wikipedia.org/wiki/Pentium_III
|
CHECK_UARCH(arch, 0, 6, 0, 8, NA, "P6 Pentium III", UARCH_P6, 180)
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 9, NA, "P6 (Pentium M)", UARCH_P6_PENTIUM_III, 130)
|
CHECK_UARCH(arch, 0, 6, 0, 9, NA, "P6 Pentium M", UARCH_P6, 130)
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 10, NA, "P6 (Coppermine T)", UARCH_P6_PENTIUM_III, 180)
|
CHECK_UARCH(arch, 0, 6, 0, 10, NA, "P6 Pentium III", UARCH_P6, 180)
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 11, NA, "P6 (Tualatin)", UARCH_P6_PENTIUM_III, 130)
|
CHECK_UARCH(arch, 0, 6, 0, 11, NA, "P6 Pentium III", UARCH_P6, 130)
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 13, NA, "Dothan", UARCH_DOTHAN, UNK) // process depends on core
|
CHECK_UARCH(arch, 0, 6, 0, 13, NA, "Dothan", UARCH_DOTHAN, UNK) // process depends on core
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 14, NA, "Yonah", UARCH_YONAH, 65)
|
CHECK_UARCH(arch, 0, 6, 0, 14, NA, "Yonah", UARCH_YONAH, 65)
|
||||||
CHECK_UARCH(arch, 0, 6, 0, 15, NA, "Merom", UARCH_MEROM, 65)
|
CHECK_UARCH(arch, 0, 6, 0, 15, NA, "Merom", UARCH_MEROM, 65)
|
||||||
@@ -393,16 +391,11 @@ struct uarch* get_uarch_from_cpuid_amd(uint32_t ef, uint32_t f, uint32_t em, uin
|
|||||||
|
|
||||||
struct uarch* get_uarch_from_cpuid(struct cpuInfo* cpu, uint32_t dump, uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s) {
|
struct uarch* get_uarch_from_cpuid(struct cpuInfo* cpu, uint32_t dump, uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s) {
|
||||||
if(cpu->cpu_vendor == CPU_VENDOR_INTEL) {
|
if(cpu->cpu_vendor == CPU_VENDOR_INTEL) {
|
||||||
struct uarch* arch = emalloc(sizeof(struct uarch));
|
|
||||||
if(dump == 0x000806E9) {
|
if(dump == 0x000806E9) {
|
||||||
if (cpu->cpu_name == NULL) {
|
|
||||||
printErr("Unable to find uarch without CPU name");
|
|
||||||
fill_uarch(arch, STRING_UNKNOWN, UARCH_UNKNOWN, UNK);
|
|
||||||
return arch;
|
|
||||||
}
|
|
||||||
|
|
||||||
// It is not possible to determine uarch only from CPUID dump (can be Kaby Lake or Amber Lake)
|
// It is not possible to determine uarch only from CPUID dump (can be Kaby Lake or Amber Lake)
|
||||||
// See issue https://github.com/Dr-Noob/cpufetch/issues/122
|
// See issue https://github.com/Dr-Noob/cpufetch/issues/122
|
||||||
|
struct uarch* arch = emalloc(sizeof(struct uarch));
|
||||||
|
|
||||||
if(strstr(cpu->cpu_name, "Y") != NULL) {
|
if(strstr(cpu->cpu_name, "Y") != NULL) {
|
||||||
fill_uarch(arch, "Amber Lake", UARCH_AMBER_LAKE, 14);
|
fill_uarch(arch, "Amber Lake", UARCH_AMBER_LAKE, 14);
|
||||||
}
|
}
|
||||||
@@ -413,14 +406,10 @@ struct uarch* get_uarch_from_cpuid(struct cpuInfo* cpu, uint32_t dump, uint32_t
|
|||||||
return arch;
|
return arch;
|
||||||
}
|
}
|
||||||
else if (dump == 0x000806EA) {
|
else if (dump == 0x000806EA) {
|
||||||
if (cpu->cpu_name == NULL) {
|
|
||||||
printErr("Unable to find uarch without CPU name");
|
|
||||||
fill_uarch(arch, STRING_UNKNOWN, UARCH_UNKNOWN, UNK);
|
|
||||||
return arch;
|
|
||||||
}
|
|
||||||
|
|
||||||
// It is not possible to determine uarch only from CPUID dump (can be Kaby Lake R or Coffee Lake U)
|
// It is not possible to determine uarch only from CPUID dump (can be Kaby Lake R or Coffee Lake U)
|
||||||
// See issue https://github.com/Dr-Noob/cpufetch/issues/149
|
// See issue https://github.com/Dr-Noob/cpufetch/issues/149
|
||||||
|
struct uarch* arch = emalloc(sizeof(struct uarch));
|
||||||
|
|
||||||
if(strstr(cpu->cpu_name, "i5-8250U") != NULL ||
|
if(strstr(cpu->cpu_name, "i5-8250U") != NULL ||
|
||||||
strstr(cpu->cpu_name, "i5-8350U") != NULL ||
|
strstr(cpu->cpu_name, "i5-8350U") != NULL ||
|
||||||
strstr(cpu->cpu_name, "i7-8550U") != NULL ||
|
strstr(cpu->cpu_name, "i7-8550U") != NULL ||
|
||||||
@@ -439,41 +428,6 @@ struct uarch* get_uarch_from_cpuid(struct cpuInfo* cpu, uint32_t dump, uint32_t
|
|||||||
return get_uarch_from_cpuid_amd(ef, f, em, m, s);
|
return get_uarch_from_cpuid_amd(ef, f, em, m, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we cannot get the CPU name from CPUID, try to infer it from uarch
|
|
||||||
char* infer_cpu_name_from_uarch(struct uarch* arch) {
|
|
||||||
char* cpu_name = NULL;
|
|
||||||
if (arch == NULL) {
|
|
||||||
printErr("infer_cpu_name_from_uarch: Unable to find CPU name");
|
|
||||||
cpu_name = ecalloc(strlen(STRING_UNKNOWN) + 1, sizeof(char));
|
|
||||||
strcpy(cpu_name, STRING_UNKNOWN);
|
|
||||||
return cpu_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *str = NULL;
|
|
||||||
|
|
||||||
if (arch->uarch == UARCH_P5)
|
|
||||||
str = "Intel Pentium";
|
|
||||||
else if (arch->uarch == UARCH_P5_MMX)
|
|
||||||
str = "Intel Pentium MMX";
|
|
||||||
else if (arch->uarch == UARCH_P6_PENTIUM_II)
|
|
||||||
str = "Intel Pentium II";
|
|
||||||
else if (arch->uarch == UARCH_P6_PENTIUM_III)
|
|
||||||
str = "Intel Pentium III";
|
|
||||||
else
|
|
||||||
printErr("Unable to find name from uarch: %d", arch->uarch);
|
|
||||||
|
|
||||||
if (str == NULL) {
|
|
||||||
cpu_name = ecalloc(strlen(STRING_UNKNOWN) + 1, sizeof(char));
|
|
||||||
strcpy(cpu_name, STRING_UNKNOWN);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cpu_name = ecalloc(strlen(str) + 1, sizeof(char));
|
|
||||||
strcpy(cpu_name, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cpu_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool vpus_are_AVX512(struct cpuInfo* cpu) {
|
bool vpus_are_AVX512(struct cpuInfo* cpu) {
|
||||||
return cpu->arch->uarch != UARCH_ICE_LAKE &&
|
return cpu->arch->uarch != UARCH_ICE_LAKE &&
|
||||||
cpu->arch->uarch != UARCH_TIGER_LAKE &&
|
cpu->arch->uarch != UARCH_TIGER_LAKE &&
|
||||||
@@ -544,6 +498,9 @@ char* get_str_process(struct cpuInfo* cpu) {
|
|||||||
if(process == UNK) {
|
if(process == UNK) {
|
||||||
snprintf(str, strlen(STRING_UNKNOWN)+1, STRING_UNKNOWN);
|
snprintf(str, strlen(STRING_UNKNOWN)+1, STRING_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
else if(process > 100) {
|
||||||
|
sprintf(str, "%.2fum", (double)process/100);
|
||||||
|
}
|
||||||
else if(process > 0){
|
else if(process > 0){
|
||||||
sprintf(str, "%dnm", process);
|
sprintf(str, "%dnm", process);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
struct uarch;
|
struct uarch;
|
||||||
|
|
||||||
struct uarch* get_uarch_from_cpuid(struct cpuInfo* cpu, uint32_t dump, uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s);
|
struct uarch* get_uarch_from_cpuid(struct cpuInfo* cpu, uint32_t dump, uint32_t ef, uint32_t f, uint32_t em, uint32_t m, int s);
|
||||||
char* infer_cpu_name_from_uarch(struct uarch* arch);
|
|
||||||
bool vpus_are_AVX512(struct cpuInfo* cpu);
|
bool vpus_are_AVX512(struct cpuInfo* cpu);
|
||||||
bool is_knights_landing(struct cpuInfo* cpu);
|
bool is_knights_landing(struct cpuInfo* cpu);
|
||||||
int get_number_of_vpus(struct cpuInfo* cpu);
|
int get_number_of_vpus(struct cpuInfo* cpu);
|
||||||
|
|||||||
Reference in New Issue
Block a user