diff --git a/src/arm/midr.c b/src/arm/midr.c index aa23ad6..99382e2 100644 --- a/src/arm/midr.c +++ b/src/arm/midr.c @@ -10,6 +10,71 @@ #define STRING_UNKNOWN "Unknown" +void init_topology_struct(struct topology* topo, struct cache* cach) { + topo->total_cores = 0; + topo->physical_cores = 0; + topo->logical_cores = 0; + topo->smt_available = 0; + topo->smt_supported = 0; + topo->sockets = 0; + topo->cach = cach; +} + +void init_cache_struct(struct cache* cach) { + cach->L1i = malloc(sizeof(struct cach)); + cach->L1d = malloc(sizeof(struct cach)); + cach->L2 = malloc(sizeof(struct cach)); + cach->L3 = malloc(sizeof(struct cach)); + + cach->cach_arr = malloc(sizeof(struct cach*) * 4); + cach->cach_arr[0] = cach->L1i; + cach->cach_arr[1] = cach->L1d; + cach->cach_arr[2] = cach->L2; + cach->cach_arr[3] = cach->L3; + + cach->max_cache_level = 0; + cach->L1i->exists = false; + cach->L1d->exists = false; + cach->L2->exists = false; + cach->L3->exists = false; +} + +struct cache* get_cache_info(struct cpuInfo* cpu) { + struct cache* cach = malloc(sizeof(struct cache)); + init_cache_struct(cach); + + cach->max_cache_level = 2; + for(int i=0; i < cach->max_cache_level + 1; i++) { + cach->cach_arr[i]->exists = true; + cach->cach_arr[i]->size = 0; + } + + return cach; +} + +struct frequency* get_frequency_info(struct cpuInfo* cpu) { + struct frequency* freq = malloc(sizeof(struct frequency)); + + freq->base = UNKNOWN_FREQ; + freq->max = get_max_freq_from_file(); + + return freq; +} + +struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach) { + struct topology* topo = malloc(sizeof(struct topology)); + init_topology_struct(topo, cach); + + topo->total_cores = get_ncores_from_cpuinfo(); + topo->physical_cores = topo->total_cores; + topo->logical_cores = topo->total_cores; + topo->smt_available = 1; + topo->smt_supported = 0; + topo->sockets = 1; + + return topo; +} + int count_distinct(uint32_t* arr, int n) { int res = 1; @@ -81,10 +146,16 @@ struct cpuInfo* get_cpu_info() { while(midr_array[midr_idx] == midr_array[tmp_midr_idx]) tmp_midr_idx++; midr_idx = tmp_midr_idx; } + ptr->next_cpu = NULL; + ptr->midr = midr_array[midr_idx]; ptr->arch = get_uarch_from_midr(ptr->midr, ptr); + + ptr->freq = get_frequency_info(ptr); + ptr->cach = get_cache_info(ptr); + ptr->topo = get_topology_info(ptr, ptr->cach); } - + cpu->num_cpus = sockets; cpu->hv = malloc(sizeof(struct hypervisor)); cpu->hv->present = false; @@ -95,71 +166,6 @@ struct cpuInfo* get_cpu_info() { return cpu; } -void init_topology_struct(struct topology* topo, struct cache* cach) { - topo->total_cores = 0; - topo->physical_cores = 0; - topo->logical_cores = 0; - topo->smt_available = 0; - topo->smt_supported = 0; - topo->sockets = 0; - topo->cach = cach; -} - -void init_cache_struct(struct cache* cach) { - cach->L1i = malloc(sizeof(struct cach)); - cach->L1d = malloc(sizeof(struct cach)); - cach->L2 = malloc(sizeof(struct cach)); - cach->L3 = malloc(sizeof(struct cach)); - - cach->cach_arr = malloc(sizeof(struct cach*) * 4); - cach->cach_arr[0] = cach->L1i; - cach->cach_arr[1] = cach->L1d; - cach->cach_arr[2] = cach->L2; - cach->cach_arr[3] = cach->L3; - - cach->max_cache_level = 0; - cach->L1i->exists = false; - cach->L1d->exists = false; - cach->L2->exists = false; - cach->L3->exists = false; -} - -struct cache* get_cache_info(struct cpuInfo* cpu) { - struct cache* cach = malloc(sizeof(struct cache)); - init_cache_struct(cach); - - cach->max_cache_level = 2; - for(int i=0; i < cach->max_cache_level + 1; i++) { - cach->cach_arr[i]->exists = true; - cach->cach_arr[i]->size = 0; - } - - return cach; -} - -struct frequency* get_frequency_info(struct cpuInfo* cpu) { - struct frequency* freq = malloc(sizeof(struct frequency)); - - freq->base = UNKNOWN_FREQ; - freq->max = get_max_freq_from_file(); - - return freq; -} - -struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach) { - struct topology* topo = malloc(sizeof(struct topology)); - init_topology_struct(topo, cach); - - topo->total_cores = get_ncores_from_cpuinfo(); - topo->physical_cores = topo->total_cores; - topo->logical_cores = topo->total_cores; - topo->smt_available = 1; - topo->smt_supported = 0; - topo->sockets = 1; - - return topo; -} - char* get_str_topology(struct cpuInfo* cpu, struct topology* topo, bool dual_socket) { uint32_t size = 3+7+1; char* string = malloc(sizeof(char)*size); @@ -168,20 +174,28 @@ char* get_str_topology(struct cpuInfo* cpu, struct topology* topo, bool dual_soc return string; } -char* get_str_peak_performance(struct cpuInfo* cpu, struct topology* topo, int64_t freq) { +char* get_str_peak_performance(struct cpuInfo* cpu) { //7 for GFLOP/s and 6 for digits,eg 412.14 uint32_t size = 7+6+1+1; assert(strlen(STRING_UNKNOWN)+1 <= size); char* string = malloc(sizeof(char)*size); - + struct cpuInfo* ptr = cpu; + //First check we have consistent data - if(freq == UNKNOWN_FREQ) { - snprintf(string,strlen(STRING_UNKNOWN)+1,STRING_UNKNOWN); - return string; + for(int i=0; i < cpu->num_cpus; ptr = ptr->next_cpu, i++) { + if(get_freq(ptr->freq) == UNKNOWN_FREQ) { + snprintf(string, strlen(STRING_UNKNOWN)+1, STRING_UNKNOWN); + return string; + } } - double flops = topo->physical_cores * topo->sockets * (freq*1000000); - + double flops; + + ptr = cpu; + for(int i=0; i < cpu->num_cpus; ptr = ptr->next_cpu, i++) { + flops += ptr->topo->total_cores * (get_freq(ptr->freq) * 1000000); + } + if(flops >= (double)1000000000000.0) snprintf(string,size,"%.2f TFLOP/s",flops/1000000000000); else if(flops >= 1000000000.0) @@ -215,4 +229,3 @@ void print_debug(struct cpuInfo* cpu) { void free_topo_struct(struct topology* topo) { free(topo); } - diff --git a/src/arm/midr.h b/src/arm/midr.h index 68517df..1084ef7 100644 --- a/src/arm/midr.h +++ b/src/arm/midr.h @@ -11,7 +11,7 @@ struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach); uint32_t get_nsockets(struct topology* topo); char* get_soc_name(struct cpuInfo* cpu); char* get_str_topology(struct cpuInfo* cpu, struct topology* topo, bool dual_socket); -char* get_str_peak_performance(struct cpuInfo* cpu, struct topology* topo, int64_t freq); +char* get_str_peak_performance(struct cpuInfo* cpu); void print_debug(struct cpuInfo* cpu); void free_topo_struct(struct topology* topo); diff --git a/src/common/cpu.h b/src/common/cpu.h index f1ab813..05a28bb 100644 --- a/src/common/cpu.h +++ b/src/common/cpu.h @@ -56,51 +56,6 @@ struct hypervisor { VENDOR hv_vendor; }; -struct cpuInfo { -#ifdef ARCH_X86 - bool AVX; - bool AVX2; - bool AVX512; - bool SSE; - bool SSE2; - bool SSE3; - bool SSSE3; - bool SSE4a; - bool SSE4_1; - bool SSE4_2; - bool FMA3; - bool FMA4; -#endif - bool AES; - bool SHA; - - VENDOR cpu_vendor; - struct uarch* arch; - struct hypervisor* hv; - -#ifdef ARCH_X86 - // CPU name from model - char* cpu_name; - // Max cpuids levels - uint32_t maxLevels; - // Max cpuids extended levels - uint32_t maxExtendedLevels; -#elif ARCH_ARM - // Main ID register - uint32_t midr; -#endif - -#ifdef ARCH_ARM - VENDOR soc; - char* soc_name; - // If SoC contains more than one CPU and they - // are different, the others will be stored in - // the next_cpu field - struct cpuInfo* next_cpu; - uint8_t num_cpus; -#endif -}; - struct cach { int32_t size; uint8_t num_caches; @@ -131,6 +86,54 @@ struct topology { #endif }; +struct cpuInfo { +#ifdef ARCH_X86 + bool AVX; + bool AVX2; + bool AVX512; + bool SSE; + bool SSE2; + bool SSE3; + bool SSSE3; + bool SSE4a; + bool SSE4_1; + bool SSE4_2; + bool FMA3; + bool FMA4; +#endif + bool AES; + bool SHA; + + VENDOR cpu_vendor; + struct uarch* arch; + struct hypervisor* hv; + struct frequency* freq; + struct cache* cach; + struct topology* topo; + +#ifdef ARCH_X86 + // CPU name from model + char* cpu_name; + // Max cpuids levels + uint32_t maxLevels; + // Max cpuids extended levels + uint32_t maxExtendedLevels; +#elif ARCH_ARM + // Main ID register + uint32_t midr; +#endif + +#ifdef ARCH_ARM + VENDOR soc; + char* soc_name; + // If SoC contains more than one CPU and they + // are different, the others will be stored in + // the next_cpu field + struct cpuInfo* next_cpu; + uint8_t num_cpus; +#endif +}; + #ifdef ARCH_X86 char* get_str_cpu_name(struct cpuInfo* cpu); #endif diff --git a/src/common/main.c b/src/common/main.c index 62fe137..2ca4862 100644 --- a/src/common/main.c +++ b/src/common/main.c @@ -80,20 +80,8 @@ int main(int argc, char* argv[]) { print_debug(cpu); return EXIT_SUCCESS; } - - struct frequency* freq = get_frequency_info(cpu); - if(freq == NULL) - return EXIT_FAILURE; - - struct cache* cach = get_cache_info(cpu); - if(cach == NULL) - return EXIT_FAILURE; - - struct topology* topo = get_topology_info(cpu, cach); - if(topo == NULL) - return EXIT_FAILURE; - - if(print_cpufetch(cpu, cach, freq, topo, get_style(), get_colors())) + + if(print_cpufetch(cpu, get_style(), get_colors())) return EXIT_SUCCESS; else return EXIT_FAILURE; diff --git a/src/common/printer.c b/src/common/printer.c index 317191a..c8766f7 100644 --- a/src/common/printer.c +++ b/src/common/printer.c @@ -403,23 +403,23 @@ void print_ascii(struct ascii* art) { } -bool print_cpufetch_x86(struct ascii* art, struct cpuInfo* cpu, struct cache* cach, struct frequency* freq, struct topology* topo, struct colors* cs) { +bool print_cpufetch_x86(struct ascii* art, struct cpuInfo* cpu, struct colors* cs) { char* uarch = get_str_uarch(cpu); char* manufacturing_process = get_str_process(cpu); - char* sockets = get_str_sockets(topo); - char* max_frequency = get_str_freq(freq); - char* n_cores = get_str_topology(cpu, topo, false); - char* n_cores_dual = get_str_topology(cpu, topo, true); + char* sockets = get_str_sockets(cpu->topo); + char* max_frequency = get_str_freq(cpu->freq); + char* n_cores = get_str_topology(cpu, cpu->topo, false); + char* n_cores_dual = get_str_topology(cpu, cpu->topo, true); char* cpu_name = get_str_cpu_name(cpu); char* avx = get_str_avx(cpu); char* fma = get_str_fma(cpu); - char* l1i = get_str_l1i(topo->cach); - char* l1d = get_str_l1d(topo->cach); - char* l2 = get_str_l2(topo->cach); - char* l3 = get_str_l3(topo->cach); - char* pp = get_str_peak_performance(cpu,topo,get_freq(freq)); + char* l1i = get_str_l1i(cpu->cach); + char* l1d = get_str_l1d(cpu->cach); + char* l2 = get_str_l2(cpu->cach); + char* l3 = get_str_l3(cpu->cach); + char* pp = get_str_peak_performance(cpu,cpu->topo,get_freq(cpu->freq)); setAttribute(art,ATTRIBUTE_NAME,cpu_name); if(cpu->hv->present) { @@ -428,7 +428,7 @@ bool print_cpufetch_x86(struct ascii* art, struct cpuInfo* cpu, struct cache* ca setAttribute(art,ATTRIBUTE_UARCH,uarch); setAttribute(art,ATTRIBUTE_TECHNOLOGY,manufacturing_process); setAttribute(art,ATTRIBUTE_FREQUENCY,max_frequency); - uint32_t socket_num = get_nsockets(topo); + uint32_t socket_num = get_nsockets(cpu->topo); if (socket_num > 1) { setAttribute(art, ATTRIBUTE_SOCKETS, sockets); setAttribute(art, ATTRIBUTE_NCORES,n_cores); @@ -471,9 +471,9 @@ bool print_cpufetch_x86(struct ascii* art, struct cpuInfo* cpu, struct cache* ca free(art); if(cs != NULL) free_colors_struct(cs); - free_cache_struct(cach); - free_topo_struct(topo); - free_freq_struct(freq); + free_cache_struct(cpu->cach); + free_topo_struct(cpu->topo); + free_freq_struct(cpu->freq); free_cpuinfo_struct(cpu); return true; @@ -539,7 +539,7 @@ void print_ascii(struct ascii* art) { } -bool print_cpufetch_arm(struct ascii* art, struct cpuInfo* cpu, struct cache* cach, struct frequency* freq, struct topology* topo, struct colors* cs) { +bool print_cpufetch_arm(struct ascii* art, struct cpuInfo* cpu, struct colors* cs) { char* manufacturing_process = get_str_process(cpu); char* soc_name = get_soc_name(cpu); setAttribute(art,ATTRIBUTE_SOC,soc_name); @@ -547,12 +547,12 @@ bool print_cpufetch_arm(struct ascii* art, struct cpuInfo* cpu, struct cache* ca if(cpu->num_cpus == 1) { char* uarch = get_str_uarch(cpu); - char* max_frequency = get_str_freq(freq); - char* n_cores = get_str_topology(cpu, topo, false); - char* l1i = get_str_l1i(topo->cach); - char* l1d = get_str_l1d(topo->cach); - char* l2 = get_str_l2(topo->cach); - char* l3 = get_str_l3(topo->cach); + char* max_frequency = get_str_freq(cpu->freq); + char* n_cores = get_str_topology(cpu, cpu->topo, false); + char* l1i = get_str_l1i(cpu->cach); + char* l1d = get_str_l1d(cpu->cach); + char* l2 = get_str_l2(cpu->cach); + char* l3 = get_str_l3(cpu->cach); setAttribute(art,ATTRIBUTE_UARCH,uarch); setAttribute(art,ATTRIBUTE_FREQUENCY,max_frequency); @@ -571,35 +571,18 @@ bool print_cpufetch_arm(struct ascii* art, struct cpuInfo* cpu, struct cache* ca free(l2); } else { - struct cpuInfo* ptr; - int i = 1; - for(ptr = cpu; ptr != NULL; ptr = ptr->next_cpu, i++) { + struct cpuInfo* ptr = cpu; + for(int i = 0; i < cpu->num_cpus; ptr = ptr->next_cpu, i++) { char* uarch = get_str_uarch(ptr); - char* max_frequency = get_str_freq(freq); - char* n_cores = get_str_topology(cpu, topo, false); - char* l1i = get_str_l1i(topo->cach); - char* l1d = get_str_l1d(topo->cach); - char* l2 = get_str_l2(topo->cach); - char* l3 = get_str_l3(topo->cach); - - /* - switch(i) { - case 1: - setAttribute(art, ATTRIBUTE_CPU_NUM_1, NULL); - break; - case 2: - setAttribute(art, ATTRIBUTE_CPU_NUM_2, NULL); - break; - case 3: - setAttribute(art, ATTRIBUTE_CPU_NUM_3, NULL); - break; - default: - printBug("SoC has more than 3 CPUs, which is not supported!"); - return false; - }*/ + char* max_frequency = get_str_freq(ptr->freq); + char* n_cores = get_str_topology(ptr, ptr->topo, false); + char* l1i = get_str_l1i(ptr->cach); + char* l1d = get_str_l1d(ptr->cach); + char* l2 = get_str_l2(ptr->cach); + char* l3 = get_str_l3(ptr->cach); char* cpu_num = malloc(sizeof(char) * 6); - sprintf(cpu_num, "CPU %d:", i); + sprintf(cpu_num, "CPU %d:", i+1); setAttribute(art, ATTRIBUTE_CPU_NUM, cpu_num); setAttribute(art, ATTRIBUTE_UARCH, uarch); setAttribute(art, ATTRIBUTE_FREQUENCY, max_frequency); @@ -612,7 +595,7 @@ bool print_cpufetch_arm(struct ascii* art, struct cpuInfo* cpu, struct cache* ca } } } - char* pp = get_str_peak_performance(cpu,topo,get_freq(freq)); + char* pp = get_str_peak_performance(cpu); setAttribute(art,ATTRIBUTE_PEAK,pp); if(art->n_attributes_set > NUMBER_OF_LINES) { @@ -631,16 +614,15 @@ bool print_cpufetch_arm(struct ascii* art, struct cpuInfo* cpu, struct cache* ca free(art); if(cs != NULL) free_colors_struct(cs); - free_cache_struct(cach); - free_topo_struct(topo); - free_freq_struct(freq); + free_cache_struct(cpu->cach); + free_topo_struct(cpu->topo); free_cpuinfo_struct(cpu); return true; } #endif -bool print_cpufetch(struct cpuInfo* cpu, struct cache* cach, struct frequency* freq, struct topology* topo, STYLE s, struct colors* cs) { +bool print_cpufetch(struct cpuInfo* cpu, STYLE s, struct colors* cs) { // Sanity check of ASCII arts for(int i=0; i < 4; i++) { const char* ascii = ASCII_ARRAY[i]; @@ -655,8 +637,8 @@ bool print_cpufetch(struct cpuInfo* cpu, struct cache* cach, struct frequency* f return false; #ifdef ARCH_X86 - return print_cpufetch_x86(art, cpu, cach, freq, topo, cs); + return print_cpufetch_x86(art, cpu, cs); #elif ARCH_ARM - return print_cpufetch_arm(art, cpu, cach, freq, topo, cs); + return print_cpufetch_arm(art, cpu, cs); #endif } diff --git a/src/common/printer.h b/src/common/printer.h index 8e32d49..d3df19a 100644 --- a/src/common/printer.h +++ b/src/common/printer.h @@ -19,6 +19,6 @@ typedef int STYLE; void print_levels(struct cpuInfo* cpu); #endif -bool print_cpufetch(struct cpuInfo* cpu, struct cache* cach, struct frequency* freq, struct topology* topo, STYLE s, struct colors* cs); +bool print_cpufetch(struct cpuInfo* cpu, STYLE s, struct colors* cs); #endif diff --git a/src/x86/cpuid.c b/src/x86/cpuid.c index 4173c1b..7f66b70 100755 --- a/src/x86/cpuid.c +++ b/src/x86/cpuid.c @@ -322,7 +322,10 @@ struct cpuInfo* get_cpu_info() { } cpu->arch = get_cpu_uarch(cpu); - + cpu->freq = get_frequency_info(cpu); + cpu->cach = get_cache_info(cpu); + cpu->topo = get_topology_info(cpu, cpu->cach); + return cpu; }