mirror of
https://github.com/Dr-Noob/cpufetch.git
synced 2026-03-25 16:00:39 +01:00
Compare commits
9 Commits
printer-bu
...
fix-accura
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14cee5be6b | ||
|
|
b6eb450eb3 | ||
|
|
4ccafdc4fa | ||
|
|
dc9b111e85 | ||
|
|
5093575f11 | ||
|
|
dc251a457e | ||
|
|
ee69cffdbb | ||
|
|
de4f47a400 | ||
|
|
5833601178 |
@@ -34,6 +34,12 @@ int64_t get_freq(struct frequency* freq) {
|
|||||||
return freq->max;
|
return freq->max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ARCH_X86
|
||||||
|
int64_t get_freq_pp(struct frequency* freq) {
|
||||||
|
return freq->max_pp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(ARCH_X86) || defined(ARCH_PPC)
|
#if defined(ARCH_X86) || defined(ARCH_PPC)
|
||||||
char* get_str_cpu_name(struct cpuInfo* cpu, bool fcpuname) {
|
char* get_str_cpu_name(struct cpuInfo* cpu, bool fcpuname) {
|
||||||
#ifdef ARCH_X86
|
#ifdef ARCH_X86
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ struct frequency {
|
|||||||
int32_t max;
|
int32_t max;
|
||||||
// Indicates if max frequency was measured
|
// Indicates if max frequency was measured
|
||||||
bool measured;
|
bool measured;
|
||||||
|
#ifdef ARCH_X86
|
||||||
|
// Max frequency when running vectorized code.
|
||||||
|
// Used only for peak performance computation.
|
||||||
|
int32_t max_pp;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hypervisor {
|
struct hypervisor {
|
||||||
@@ -188,6 +193,8 @@ struct cpuInfo {
|
|||||||
#ifdef ARCH_X86
|
#ifdef ARCH_X86
|
||||||
// The index of the first core in the module
|
// The index of the first core in the module
|
||||||
uint32_t first_core_id;
|
uint32_t first_core_id;
|
||||||
|
// The index of this module
|
||||||
|
uint32_t module_id;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -200,6 +207,9 @@ uint32_t get_nsockets(struct topology* topo);
|
|||||||
|
|
||||||
VENDOR get_cpu_vendor(struct cpuInfo* cpu);
|
VENDOR get_cpu_vendor(struct cpuInfo* cpu);
|
||||||
int64_t get_freq(struct frequency* freq);
|
int64_t get_freq(struct frequency* freq);
|
||||||
|
#ifdef ARCH_X86
|
||||||
|
int64_t get_freq_pp(struct frequency* freq);
|
||||||
|
#endif
|
||||||
|
|
||||||
char* get_str_aes(struct cpuInfo* cpu);
|
char* get_str_aes(struct cpuInfo* cpu);
|
||||||
char* get_str_sha(struct cpuInfo* cpu);
|
char* get_str_sha(struct cpuInfo* cpu);
|
||||||
|
|||||||
@@ -210,18 +210,14 @@ int64_t get_peak_performance(struct cpuInfo* cpu, bool accurate_pp) {
|
|||||||
|
|
||||||
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++) {
|
||||||
struct topology* topo = ptr->topo;
|
struct topology* topo = ptr->topo;
|
||||||
int64_t max_freq = get_freq(ptr->freq);
|
int64_t freq = get_freq(ptr->freq);
|
||||||
|
|
||||||
int64_t freq;
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if(accurate_pp)
|
if(accurate_pp)
|
||||||
freq = measure_frequency(ptr);
|
freq = get_freq_pp(ptr->freq);
|
||||||
else
|
|
||||||
freq = max_freq;
|
|
||||||
#else
|
#else
|
||||||
// Silence compiler warning
|
// Silence compiler warning
|
||||||
(void)(accurate_pp);
|
(void)(accurate_pp);
|
||||||
freq = max_freq;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//First, check we have consistent data
|
//First, check we have consistent data
|
||||||
@@ -450,6 +446,23 @@ int32_t get_core_type(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
// Gets the max frequency for estimating the peak performance
|
||||||
|
// and fills in the passed cpuInfo parameter.
|
||||||
|
void fill_frequency_info_pp(struct cpuInfo* cpu) {
|
||||||
|
int32_t unused;
|
||||||
|
int32_t *max_freq_pp_vec = malloc(sizeof(int32_t) * cpu->num_cpus);
|
||||||
|
struct cpuInfo* ptr = cpu;
|
||||||
|
|
||||||
|
for (uint32_t i=0; i < cpu->num_cpus; i++) {
|
||||||
|
set_cpu_module(i, cpu->num_cpus, &unused);
|
||||||
|
|
||||||
|
ptr->freq->max_pp = measure_frequency(ptr, max_freq_pp_vec);
|
||||||
|
ptr = ptr->next_cpu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
struct cpuInfo* get_cpu_info(void) {
|
struct cpuInfo* get_cpu_info(void) {
|
||||||
struct cpuInfo* cpu = emalloc(sizeof(struct cpuInfo));
|
struct cpuInfo* cpu = emalloc(sizeof(struct cpuInfo));
|
||||||
cpu->peak_performance = -1;
|
cpu->peak_performance = -1;
|
||||||
@@ -546,6 +559,7 @@ struct cpuInfo* get_cpu_info(void) {
|
|||||||
ptr->core_type = get_core_type();
|
ptr->core_type = get_core_type();
|
||||||
}
|
}
|
||||||
ptr->first_core_id = first_core;
|
ptr->first_core_id = first_core;
|
||||||
|
ptr->module_id = i;
|
||||||
ptr->feat = get_features_info(ptr);
|
ptr->feat = get_features_info(ptr);
|
||||||
|
|
||||||
ptr->arch = get_cpu_uarch(ptr);
|
ptr->arch = get_cpu_uarch(ptr);
|
||||||
@@ -570,6 +584,13 @@ struct cpuInfo* get_cpu_info(void) {
|
|||||||
if(ptr->topo == NULL) return cpu;
|
if(ptr->topo == NULL) return cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
// If accurate_pp is requested, we need to get the max frequency
|
||||||
|
// after fetching the topology for all CPU modules, since the topology
|
||||||
|
// is required by fill_frequency_info_pp
|
||||||
|
if (accurate_pp()) fill_frequency_info_pp(cpu);
|
||||||
|
#endif
|
||||||
|
|
||||||
cpu->peak_performance = get_peak_performance(cpu, accurate_pp());
|
cpu->peak_performance = get_peak_performance(cpu, accurate_pp());
|
||||||
|
|
||||||
return cpu;
|
return cpu;
|
||||||
@@ -1005,6 +1026,7 @@ struct frequency* get_frequency_info(struct cpuInfo* cpu) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
freq->max_pp = UNKNOWN_DATA;
|
||||||
return freq;
|
return freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,12 @@
|
|||||||
#define FREQ_VECTOR_SIZE 1<<16
|
#define FREQ_VECTOR_SIZE 1<<16
|
||||||
|
|
||||||
struct freq_thread {
|
struct freq_thread {
|
||||||
|
// Inputs
|
||||||
|
struct cpuInfo* cpu;
|
||||||
bool end;
|
bool end;
|
||||||
bool measure;
|
bool measure;
|
||||||
double freq;
|
// Output
|
||||||
|
int32_t *max_pp;
|
||||||
};
|
};
|
||||||
|
|
||||||
double vector_average_harmonic(double* v, int len) {
|
double vector_average_harmonic(double* v, int len) {
|
||||||
@@ -48,6 +51,7 @@ void* measure_freq(void *freq_ptr) {
|
|||||||
char* line = NULL;
|
char* line = NULL;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
ssize_t read;
|
ssize_t read;
|
||||||
|
struct cpuInfo* cpu = freq->cpu;
|
||||||
|
|
||||||
int v = 0;
|
int v = 0;
|
||||||
double* freq_vector = malloc(sizeof(double) * FREQ_VECTOR_SIZE);
|
double* freq_vector = malloc(sizeof(double) * FREQ_VECTOR_SIZE);
|
||||||
@@ -76,18 +80,43 @@ void* measure_freq(void *freq_ptr) {
|
|||||||
sleep_ms(500);
|
sleep_ms(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
freq->freq = vector_average_harmonic(freq_vector, v);
|
if (cpu->hybrid_flag) {
|
||||||
printWarn("AVX2 measured freq=%f\n", freq->freq);
|
// We have an heterogeneous architecture. After measuring the
|
||||||
|
// frequency for all cores, we now need to compute the average
|
||||||
|
// independently for each CPU module.
|
||||||
|
struct cpuInfo* ptr = cpu;
|
||||||
|
double* freq_vector_ptr = freq_vector;
|
||||||
|
|
||||||
|
for (int i=0; i < cpu->num_cpus; ptr = ptr->next_cpu, i++) {
|
||||||
|
freq->max_pp[i] = vector_average_harmonic(freq_vector_ptr, ptr->topo->total_cores_module);
|
||||||
|
printWarn("AVX2 measured freq=%d (module %d)", freq->max_pp[i], i);
|
||||||
|
|
||||||
|
freq_vector_ptr = freq_vector_ptr + ptr->topo->total_cores_module;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
freq->max_pp[0] = vector_average_harmonic(freq_vector, v);
|
||||||
|
printWarn("AVX2 measured freq=%d\n", freq->max_pp[0]);
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t measure_frequency(struct cpuInfo* cpu) {
|
int32_t measure_frequency(struct cpuInfo* cpu, int32_t *max_freq_pp_vec) {
|
||||||
|
if (cpu->hybrid_flag && cpu->module_id > 0) {
|
||||||
|
// We have a hybrid architecture and we have already
|
||||||
|
// measured the frequency for this module in a previous
|
||||||
|
// call to this function, so now just return it.
|
||||||
|
return max_freq_pp_vec[cpu->module_id];
|
||||||
|
}
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
int num_spaces;
|
int num_spaces;
|
||||||
struct freq_thread* freq_struct = malloc(sizeof(struct freq_thread));
|
struct freq_thread* freq_struct = malloc(sizeof(struct freq_thread));
|
||||||
freq_struct->end = false;
|
freq_struct->end = false;
|
||||||
freq_struct->measure = false;
|
freq_struct->measure = false;
|
||||||
|
freq_struct->cpu = cpu;
|
||||||
|
freq_struct->max_pp = max_freq_pp_vec;
|
||||||
|
|
||||||
void* (*compute_function)(void*);
|
void* (*compute_function)(void*);
|
||||||
|
|
||||||
@@ -159,5 +188,5 @@ int64_t measure_frequency(struct cpuInfo* cpu) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("\r%*c", num_spaces, ' ');
|
printf("\r%*c", num_spaces, ' ');
|
||||||
return freq_struct->freq;
|
return max_freq_pp_vec[0];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,6 @@
|
|||||||
#define MEASURE_TIME_SECONDS 5
|
#define MEASURE_TIME_SECONDS 5
|
||||||
#define LOOP_ITERS 100000000
|
#define LOOP_ITERS 100000000
|
||||||
|
|
||||||
int64_t measure_frequency(struct cpuInfo* cpu);
|
int32_t measure_frequency(struct cpuInfo* cpu, int32_t *max_freq_pp_vec);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user