From 4d1d14d2a71f5182dfc40abb5eb03d2bd38fc496 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Sat, 31 Jul 2021 17:43:02 +0200 Subject: [PATCH] [v0.98][PPC] Add altivec detection and peak performance output --- src/common/printer.c | 23 +++++++++++++---------- src/common/printer.h | 4 +++- src/ppc/ppc.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/ppc/ppc.h | 2 ++ src/ppc/uarch.c | 17 +++++++++++++++++ src/ppc/uarch.h | 1 + 6 files changed, 80 insertions(+), 11 deletions(-) diff --git a/src/common/printer.c b/src/common/printer.c index 8829ca2..e6e5eec 100644 --- a/src/common/printer.c +++ b/src/common/printer.c @@ -64,6 +64,8 @@ enum { #ifdef ARCH_X86 ATTRIBUTE_AVX, ATTRIBUTE_FMA, +#elif ARCH_PPC + ATTRIBUTE_ALTIVEC, #elif ARCH_ARM ATTRIBUTE_FEATURES, #endif @@ -91,8 +93,10 @@ static const char* ATTRIBUTE_FIELDS [] = { #ifdef ARCH_X86 "AVX:", "FMA:", -#elif defined(ARCH_ARM) || defined(ARCH_PPC) - "Features: ", +#elif ARCH_PPC + "Altivec: ", +#elif defined(ARCH_ARM) + "Features: ", #endif "L1i Size:", "L1d Size:", @@ -572,13 +576,14 @@ bool print_cpufetch_ppc(struct cpuInfo* cpu, STYLE s, struct colors* cs) { 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* altivec = get_str_altivec(cpu); /* 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));*/ + 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); /* @@ -591,23 +596,21 @@ bool print_cpufetch_ppc(struct cpuInfo* cpu, STYLE s, struct colors* cs) { uint32_t socket_num = get_nsockets(cpu->topo); if (socket_num > 1) { setAttribute(art, ATTRIBUTE_SOCKETS, sockets); - setAttribute(art, ATTRIBUTE_NCORES,n_cores); + setAttribute(art, ATTRIBUTE_NCORES, n_cores); setAttribute(art, ATTRIBUTE_NCORES_DUAL, n_cores_dual); } else { - setAttribute(art,ATTRIBUTE_NCORES,n_cores); + setAttribute(art,ATTRIBUTE_NCORES, n_cores); } + setAttribute(art,ATTRIBUTE_ALTIVEC, altivec); /* - setAttribute(art,ATTRIBUTE_AVX,avx); - setAttribute(art,ATTRIBUTE_FMA,fma); setAttribute(art,ATTRIBUTE_L1i,l1i); setAttribute(art,ATTRIBUTE_L1d,l1d); setAttribute(art,ATTRIBUTE_L2,l2); if(l3 != NULL) { setAttribute(art,ATTRIBUTE_L3,l3); - } + }*/ setAttribute(art,ATTRIBUTE_PEAK,pp); - */ if(art->n_attributes_set > NUMBER_OF_LINES) { printBug("The number of attributes set is bigger than the max that can be displayed"); diff --git a/src/common/printer.h b/src/common/printer.h index 410449e..b08d69c 100644 --- a/src/common/printer.h +++ b/src/common/printer.h @@ -7,7 +7,9 @@ typedef int STYLE; #ifdef ARCH_X86 #include "../x86/cpuid.h" -#else +#elif ARCH_PPC + #include "../ppc/ppc.h" +#elif ARCH_ARM #include "../arm/midr.h" #endif diff --git a/src/ppc/ppc.c b/src/ppc/ppc.c index 4995490..fcb443e 100644 --- a/src/ppc/ppc.c +++ b/src/ppc/ppc.c @@ -3,8 +3,10 @@ #include #include #include +#include #include "ppc.h" +#include "uarch.h" #include "udev.h" #include "../common/udev.h" @@ -146,12 +148,54 @@ struct cpuInfo* get_cpu_info() { cpu->cach = get_cache_info(cpu); cpu->topo = get_topology_info(cpu, cpu->cach); + feat->altivec = has_altivec(cpu->arch); + if(cpu->cach == NULL || cpu->topo == NULL) { return NULL; } return cpu; } +char* get_str_altivec(struct cpuInfo* cpu) { + char* string = calloc(4, sizeof(char)); + + if(cpu->feat->altivec) strcpy(string, "Yes"); + else strcpy(string, "No"); + + return string; +} + +char* get_str_peak_performance(struct cpuInfo* cpu, struct topology* topo, int64_t freq) { + /* + * Not sure about this + * PP(SP) = N_CORES * FREQUENCY * 4(If altivec) + */ + + //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); + + //First check we have consistent data + if(freq == UNKNOWN_FREQ) { + snprintf(string,strlen(STRING_UNKNOWN)+1,STRING_UNKNOWN); + return string; + } + + struct features* feat = cpu->feat; + double flops = topo->physical_cores * topo->sockets * (freq*1000000); + if(feat->altivec) flops = flops*4; + + if(flops >= (double)1000000000000.0) + snprintf(string,size,"%.2f TFLOP/s",flops/1000000000000); + else if(flops >= 1000000000.0) + snprintf(string,size,"%.2f GFLOP/s",flops/1000000000); + else + snprintf(string,size,"%.2f MFLOP/s",flops/1000000); + + return string; +} + char* get_str_topology(struct cpuInfo* cpu, struct topology* topo, bool dual_socket) { char* string; if(topo->smt_supported > 1) { diff --git a/src/ppc/ppc.h b/src/ppc/ppc.h index 1276a52..132e685 100644 --- a/src/ppc/ppc.h +++ b/src/ppc/ppc.h @@ -5,6 +5,8 @@ struct topology* get_topology_info(struct cpuInfo* cpu, struct cache* cach); struct cpuInfo* get_cpu_info(); +char* get_str_altivec(struct cpuInfo* cpu); +char* get_str_peak_performance(struct cpuInfo* cpu, struct topology* topo, int64_t freq); void print_debug(struct cpuInfo* cpu); #endif diff --git a/src/ppc/uarch.c b/src/ppc/uarch.c index d09cd5d..0c613c0 100644 --- a/src/ppc/uarch.c +++ b/src/ppc/uarch.c @@ -219,6 +219,23 @@ struct uarch* get_uarch_from_pvr(uint32_t pvr) { return arch; } +bool has_altivec(struct uarch* arch) { + switch(arch->uarch) { + case UARCH_PPC970FX: + case UARCH_PPC970MP: + case UARCH_CELLBE: + case UARCH_POWER6: + case UARCH_POWER7: + case UARCH_POWER7PLUS: + case UARCH_POWER8: + case UARCH_POWER9: + case UARCH_POWER10: + return true; + default: + return false; + } +} + char* get_str_uarch(struct cpuInfo* cpu) { return cpu->arch->uarch_str; } diff --git a/src/ppc/uarch.h b/src/ppc/uarch.h index 60c78b1..7ad20d8 100644 --- a/src/ppc/uarch.h +++ b/src/ppc/uarch.h @@ -7,6 +7,7 @@ struct uarch; struct uarch* get_uarch_from_pvr(uint32_t pvr); +bool has_altivec(struct uarch* arch); char* get_str_uarch(struct cpuInfo* cpu); char* get_str_process(struct cpuInfo* cpu); void free_uarch_struct(struct uarch* arch);