From 978f283e1a3e20fdd3eefa5f5b85f8cac67ceed4 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Thu, 29 Mar 2018 23:27:59 +0200 Subject: [PATCH] Print all information --- 01h.c | 103 +++++++++++++++++++++++++++++++ 01h.h | 8 +++ 02h.c | 4 +- Makefile | 8 ++- extended.c | 2 +- extended.h | 2 +- main.c | 54 +++++++++++++--- printer.h | 22 +++++++ udev.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++ udev.h | 44 +++++++++++++ 10 files changed, 409 insertions(+), 15 deletions(-) create mode 100644 printer.h create mode 100644 udev.c create mode 100644 udev.h diff --git a/01h.c b/01h.c index 13a1e99..27ddca0 100644 --- a/01h.c +++ b/01h.c @@ -1,5 +1,7 @@ #include #include +#include + #include "01h.h" #include "cpuid.h" @@ -36,6 +38,7 @@ struct cpuInfo { int AES; int SHA; + int nCores; int maxLevels; int maxExtendedLevels; }; @@ -61,6 +64,7 @@ struct cpuInfo* getCPUInfo() { struct cpuInfo* cpu = malloc(sizeof(struct cpuInfo)); initializeCpuInfo(cpu); + cpu->nCores = sysconf( _SC_NPROCESSORS_ONLN ); unsigned eax, ebx, ecx, edx; eax = 0x0000000; cpuid(&eax, &ebx, &ecx, &edx); @@ -88,6 +92,7 @@ struct cpuInfo* getCPUInfo() { } if (cpu->maxLevels >= 0x00000007){ eax = 0x00000007; + ecx = 0x00000000; cpuid(&eax, &ebx, &ecx, &edx); cpu->AVX2 = (ebx & ((int)1 << 5)) != 0; cpu->SHA = (ebx & ((int)1 << 29)) != 0; @@ -129,3 +134,101 @@ void debugCpuInfo(struct cpuInfo* cpu) { printf("AES=%s\n", cpu->AES ? "true" : "false"); printf("SHA=%s\n", cpu->SHA ? "true" : "false"); } + +/*** STRING FUNCTIONS ***/ + +char* getString_NumberCores(struct cpuInfo* cpu) { + char* string = malloc(sizeof(char)*2+1); + snprintf(string,2+1,"%d",cpu->nCores); + return string; +} + +char* getString_AVX(struct cpuInfo* cpu) { + //If all AVX are available, it will use up to 15 + char* string = malloc(sizeof(char)*15+1); + if(cpu->AVX == BOOLEAN_FALSE) + snprintf(string,2+1,"No"); + else if(cpu->AVX2 == BOOLEAN_FALSE) + snprintf(string,3+1,"AVX"); + else if(cpu->AVX512 == BOOLEAN_FALSE) + snprintf(string,8+1,"AVX,AVX2"); + else + snprintf(string,15+1,"AVX,AVX2,AVX512"); + + return string; +} + +char* getString_SSE(struct cpuInfo* cpu) { + char* string = malloc(sizeof(char)*33+1); + int last = 0; + int SSE_sl = 4; + int SSE2_sl = 5; + int SSE3_sl = 5; + int SSSE3_sl = 6; + int SSE4a_sl = 6; + int SSE4_1_sl = 7; + int SSE4_2_sl = 7; + + if(cpu->SSE == BOOLEAN_TRUE) { + snprintf(string+last,SSE_sl+1,"SSE,"); + last+=SSE_sl; + } + if(cpu->SSE2 == BOOLEAN_TRUE) { + snprintf(string+last,SSE2_sl+1,"SSE2,"); + last+=SSE2_sl; + } + if(cpu->SSE3 == BOOLEAN_TRUE) { + snprintf(string+last,SSE3_sl+1,"SSE3,"); + last+=SSE3_sl; + } + if(cpu->SSSE3 == BOOLEAN_TRUE) { + snprintf(string+last,SSSE3_sl+1,"SSSE3,"); + last+=SSSE3_sl; + } + if(cpu->SSE4a == BOOLEAN_TRUE) { + snprintf(string+last,SSE4a_sl+1,"SSE4a,"); + last+=SSE4a_sl; + } + if(cpu->SSE4_1 == BOOLEAN_TRUE) { + snprintf(string+last,SSE4_1_sl+1,"SSE4_1,"); + last+=SSE4_1_sl; + } + if(cpu->SSE4_2 == BOOLEAN_TRUE) { + snprintf(string+last,SSE4_2_sl+1,"SSE4_2,"); + last+=SSE4_2_sl; + } + + //Purge last comma + string[last-1] = '\0'; + return string; +} + +char* getString_FMA(struct cpuInfo* cpu) { + char* string = malloc(sizeof(char)*9+1); + if(cpu->FMA3 == BOOLEAN_FALSE) + snprintf(string,2+1,"No"); + else if(cpu->FMA4 == BOOLEAN_FALSE) + snprintf(string,4+1,"FMA3"); + else + snprintf(string,9+1,"FMA3,FMA4"); + + return string; +} + +char* getString_AES(struct cpuInfo* cpu) { + char* string = malloc(sizeof(char)*3+1); + if(cpu->AES == BOOLEAN_TRUE) + snprintf(string,3+1,"Yes"); + else + snprintf(string,2+1,"No"); + return string; +} + +char* getString_SHA(struct cpuInfo* cpu) { + char* string = malloc(sizeof(char)*3+1); + if(cpu->SHA == BOOLEAN_TRUE) + snprintf(string,3+1,"Yes"); + else + snprintf(string,2+1,"No"); + return string; +} diff --git a/01h.h b/01h.h index 9d5fbd2..ee7542f 100644 --- a/01h.h +++ b/01h.h @@ -2,7 +2,15 @@ #define __01h__ struct cpuInfo; + struct cpuInfo* getCPUInfo(); void debugCpuInfo(struct cpuInfo* cpu); +char* getString_NumberCores(struct cpuInfo* cpu); +char* getString_AVX(struct cpuInfo* cpu); +char* getString_SSE(struct cpuInfo* cpu); +char* getString_FMA(struct cpuInfo* cpu); +char* getString_AES(struct cpuInfo* cpu); +char* getString_SHA(struct cpuInfo* cpu); + #endif diff --git a/02h.c b/02h.c index 4c9a265..843ceb7 100644 --- a/02h.c +++ b/02h.c @@ -359,7 +359,7 @@ struct level2* fillLevel2(struct level2* data) { return data; } -void debugCache(struct cache* cach) { +void debugCachex(struct cache* cach) { printf("L1d=%d\n", cach->L1d); printf("L1i=%d\n", cach->L1i); printf("L2=%d\n", cach->L2); @@ -372,7 +372,7 @@ void debugTLB(struct TLB* tlb) { } void debugLevel2(struct level2* data) { - debugCache(data->cache); + debugCachex(data->cache); debugTLB(data->tlb); } diff --git a/Makefile b/Makefile index 776dbed..b9bd684 100644 --- a/Makefile +++ b/Makefile @@ -2,13 +2,15 @@ CXX=gcc CXXFLAGS=-g -SOURCE=main.c 01h.c 02h.c extended.c cpuid.c -HEADERS=01h.c 02h.h extended.h cpuid.h +SOURCE=main.c 01h.c 02h.c extended.c cpuid.c udev.c +HEADERS=01h.c 02h.h extended.h cpuid.h udev.h printer.h OUTPUT=cpufetch $(OUTPUT): Makefile $(SOURCE) $(HEADERS) $(CXX) $(CXXFLAGS) $(SOURCE) -o $(OUTPUT) +run: + ./$(OUTPUT) clean: - @rm $(OUTPUT1) $(OUTPUT2) + @rm $(OUTPUT) diff --git a/extended.c b/extended.c index 46c9fed..5714f34 100644 --- a/extended.c +++ b/extended.c @@ -1,6 +1,6 @@ #include "extended.h" -char* getCPUName() { +char* getString_CPUName() { unsigned eax, ebx, ecx, edx; //First, check we can use extended diff --git a/extended.h b/extended.h index 8beda2f..8852400 100644 --- a/extended.h +++ b/extended.h @@ -5,6 +5,6 @@ #include "cpuid.h" #include -char* getCPUName(); +char* getString_CPUName(); #endif diff --git a/main.c b/main.c index 719a632..3bb86bb 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,8 @@ #include #include +#include "printer.h" #include "01h.h" -#include "02h.h" +#include "udev.h" #include "extended.h" /*** @@ -24,13 +25,50 @@ Peak FLOPS: 512 GFLOP/s(in simple precision) ***/ int main() { - struct level2* level2 = fillLevel2(level2); - debugLevel2(level2); - freeLevel2(level2); - struct cpuInfo* cpu = getCPUInfo(cpu); - debugCpuInfo(cpu); - free(cpu); + struct cache* cach = new_cache(cach); + struct frequency* freq = new_frequency(freq); + + char* cpuName = getString_CPUName(); + char* maxFrequency = getString_MaxFrequency(freq); + char* nCores = getString_NumberCores(cpu); + char* avx = getString_AVX(cpu); + char* sse = getString_SSE(cpu); + char* fma = getString_FMA(cpu); + char* aes = getString_AES(cpu); + char* sha = getString_SHA(cpu); + char* l1 = getString_L1(cach); + char* l2 = getString_L2(cach); + char* l3 = getString_L3(cach); + + printf(TITLE_NAME"%s\n",cpuName); + printf(TITLE_ARCH"%s\n","x86_64"); + printf(TITLE_FREQUENCY"%s\n",maxFrequency); + printf(TITLE_NCORES"%s\n",nCores); + printf(TITLE_AVX"%s\n",avx); + printf(TITLE_SSE"%s\n",sse); + printf(TITLE_FMA"%s\n",fma); + printf(TITLE_AES"%s\n",aes); + printf(TITLE_SHA"%s\n",sha); + printf(TITLE_L1"%s\n",l1); + printf(TITLE_L3"%s\n",l2); + printf(TITLE_L2"%s\n",l3); + printf(TITLE_PEAK"%s\n","??? GFLOP/s"); + + free(cpuName); + free(maxFrequency); + free(nCores); + free(avx); + free(sse); + free(fma); + free(aes); + free(sha); + free(l1); + free(l2); + free(l3); + + free(cpu); + freeCache(cach); + freeFrequency(freq); - printf("%s\n",getCPUName()); } diff --git a/printer.h b/printer.h new file mode 100644 index 0000000..5fffb85 --- /dev/null +++ b/printer.h @@ -0,0 +1,22 @@ +#ifndef __PRINTER__ +#define __PRINTER__ + +//#include "ascii.h" + +//void print_ascii(int n); + +#define TITLE_NAME "Name: " +#define TITLE_ARCH "Arch: " +#define TITLE_FREQUENCY "Frecuency: " +#define TITLE_NCORES "N.Cores: " +#define TITLE_AVX "AVX: " +#define TITLE_SSE "SSE: " +#define TITLE_FMA "FMA: " +#define TITLE_AES "AES: " +#define TITLE_SHA "SHA: " +#define TITLE_L1 "L1 Size: " +#define TITLE_L2 "L2 Size: " +#define TITLE_L3 "L3 Size: " +#define TITLE_PEAK "Peak FLOPS: " + +#endif diff --git a/udev.c b/udev.c new file mode 100644 index 0000000..59cd242 --- /dev/null +++ b/udev.c @@ -0,0 +1,177 @@ +#include +#include +#include +#include + +#include "udev.h" + +struct cache { + int L1i; + int L1d; + int L2; + int L3; +}; + +struct frequency { + int max; + int min; +}; + +/*** + +Parses buf which should be expressed in the way: +xxxxK where 'x' are numbers and 'K' refers to kilobytes. +Returns the size as a int in bytes + +***/ + +int getSize(char* buf, int size) { + char* end = strstr (buf,"K"); + if(end == NULL) { + printf("ERROR in getSize(strstr)\n"); + return NO_CACHE; + } + *end = 0; + int cachsize = atoi(buf); + if(cachsize == 0) { + printf("ERROR in getSize(atoi)\n"); + return NO_CACHE; + } + return cachsize; +} + +/*** + +Returns size(in bytes) of cache described by path or +NO_CACHE if the cache doest no exists + +***/ + +//Sacar factor comun lectura +//Block pasar de 1 a 1000 +int getCache(char* path) { + FILE *file = fopen(path, "r"); + + if(file == NULL) { + //Doest not exist + return NO_CACHE; + } + + //File exists, read it + int fd = fileno(file); + int bytes_read = 0; + int offset = 0; + int block = 1; + char* buf = malloc(sizeof(char)*DEFAULT_FILE_SIZE); + memset(buf, 0, sizeof(char)*DEFAULT_FILE_SIZE); + + while ( (bytes_read = read(fd, buf+offset, block)) > 0 ) { + offset += bytes_read; + } + + int ret = getSize(buf,offset)*1024; + free(buf); + return ret; +} + +int getFrequency(char* path) { + FILE *file = fopen(path, "r"); + + if(file == NULL) { + //Doest not exist + return NO_CACHE; + } + + //File exists, read it + int fd = fileno(file); + int bytes_read = 0; + int offset = 0; + int block = 1; + char* buf = malloc(sizeof(char)*DEFAULT_FILE_SIZE); + memset(buf, 0, sizeof(char)*DEFAULT_FILE_SIZE); + + while ( (bytes_read = read(fd, buf+offset, block)) > 0 ) { + offset += bytes_read; + } + + int ret = atoi(buf); + free(buf); + if(ret == 0) { + printf("error in getFrequency\n"); + return NO_CACHE; + } + return ret/1000; +} + +/*** GET_STRING ***/ + +char* getString_L1(struct cache* cach) { + //Max 2 digits,2 for 'KB',6 for '(Data)' + //and 14 for '(Instructions)' + int size = (2*(2+2)+6+14+1); + char* string = malloc(sizeof(char)*size); + snprintf(string,size,"%dKB(Data)%dKB(Instructions)",cach->L1d/1024,cach->L1i/1024); + return string; +} + +char* getString_L2(struct cache* cach) { + //Max 4 digits and 2 for 'KB' + int size = (4+2+1); + char* string = malloc(sizeof(char)*size); + snprintf(string,size,"%dKB",cach->L2/1024); + return string; +} + +char* getString_L3(struct cache* cach) { + //Max 4 digits and 2 for 'KB' + int size = (4+2+1); + char* string = malloc(sizeof(char)*size); + snprintf(string,size,"%dKB",cach->L3/1024); + return string; +} + +char* getString_MaxFrequency(struct frequency* freq) { + //Max 4 digits and 3 for 'MHz' plus 1 for '\0' + int size = (4+3+1); + char* string = malloc(sizeof(char)*size); + snprintf(string,size,"%dMHz",freq->max); + return string; +} + +/*** CREATE DEBUGING AND FREES ***/ + +struct cache* new_cache(struct cache* cach) { + cach = malloc(sizeof(struct cache)); + cach->L1i = getCache(_PATH_CACHE_L1i); + cach->L1d = getCache(_PATH_CACHE_L1d); + cach->L2 = getCache(_PATH_CACHE_L2); + cach->L3 = getCache(_PATH_CACHE_L3); + return cach; +} + +struct frequency* new_frequency(struct frequency* freq) { + freq = malloc(sizeof(struct frequency)); + freq->max = getFrequency(_PATH_FREQUENCY_MAX); + freq->min = getFrequency(_PATH_FREQUENCY_MIN); + return freq; +} + +void debugCache(struct cache* cach) { + printf("L1i=%dB\n",cach->L1i); + printf("L1d=%dB\n",cach->L1d); + printf("L2=%dB\n",cach->L2); + printf("L3=%dB\n",cach->L3); +} + +void debugFrequency(struct frequency* freq) { + printf("max f=%dMhz\n",freq->max); + printf("min f=%dMhz\n",freq->min); +} + +void freeCache(struct cache* cach) { + free(cach); +} + +void freeFrequency(struct frequency* freq) { + free(freq); +} diff --git a/udev.h b/udev.h new file mode 100644 index 0000000..9bfe15d --- /dev/null +++ b/udev.h @@ -0,0 +1,44 @@ +#ifndef __UDEV__ +#define __UDEV__ + +/*** PATHS ***/ + +#define _PATH_SYS_SYSTEM "/sys/devices/system" +#define _PATH_SYS_CPU _PATH_SYS_SYSTEM"/cpu" +#define _PATH_ONE_CPU _PATH_SYS_CPU"/cpu0" + +#define _PATH_FREQUENCY _PATH_ONE_CPU"/cpufreq" +#define _PATH_FREQUENCY_MAX _PATH_FREQUENCY"/cpuinfo_max_freq" +#define _PATH_FREQUENCY_MIN _PATH_FREQUENCY"/cpuinfo_min_freq" + +#define _PATH_CPU_CACHE _PATH_ONE_CPU"/cache" +#define _PATH_CACHE_L1d _PATH_CPU_CACHE"/index0/size" +#define _PATH_CACHE_L1i _PATH_CPU_CACHE"/index1/size" +#define _PATH_CACHE_L2 _PATH_CPU_CACHE"/index2/size" +#define _PATH_CACHE_L3 _PATH_CPU_CACHE"/index3/size" + +/*** CONSTANTS ***/ + +#define NO_CACHE -1 +#define DEFAULT_FILE_SIZE 4096 + +/*** STRUCTS ***/ + +struct cache; +struct frequency; + +/*** FUNCTIONS ***/ + +struct cache* new_cache(struct cache* cach); +void debugCache(struct cache* cach); +void freeCache(struct cache* cach); +char* getString_L1(struct cache* cach); +char* getString_L2(struct cache* cach); +char* getString_L3(struct cache* cach); + +struct frequency* new_frequency(struct frequency* freq); +void debugFrequency(struct frequency* freq); +void freeFrequency(struct frequency* freq); +char* getString_MaxFrequency(struct frequency* freq); + +#endif