diff --git a/01h.c b/01h.c index 9d8cc9d..8aeac4d 100644 --- a/01h.c +++ b/01h.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "01h.h" #include "cpuid.h" @@ -40,6 +41,7 @@ struct cpuInfo { int AES; int SHA; + VENDOR cpu_vendor; /*** Number of threads ***/ int nThreads; /*** Threads per core(Intel HyperThreading) ***/ @@ -67,16 +69,54 @@ void initializeCpuInfo(struct cpuInfo* cpu) { cpu->SHA = BOOLEAN_FALSE; } +#define MASK 0xFF +VENDOR getCPUVendor(unsigned eax,unsigned ebx,unsigned ecx,unsigned edx) { + char name[13]; + name[__COUNTER__] = ebx & MASK; + name[__COUNTER__] = (ebx>>8) & MASK; + name[__COUNTER__] = (ebx>>16) & MASK; + name[__COUNTER__] = (ebx>>24) & MASK; + + name[__COUNTER__] = edx & MASK; + name[__COUNTER__] = (edx>>8) & MASK; + name[__COUNTER__] = (edx>>16) & MASK; + name[__COUNTER__] = (edx>>24) & MASK; + + name[__COUNTER__] = ecx & MASK; + name[__COUNTER__] = (ecx>>8) & MASK; + name[__COUNTER__] = (ecx>>16) & MASK; + name[__COUNTER__] = (ecx>>24) & MASK; + + name[__COUNTER__] = '\0'; + + if(strcmp(VENDOR_INTEL_STRING,name) == 0) + return VENDOR_INTEL; + + else if (strcmp(VENDOR_AMD_STRING,name) == 0) + return VENDOR_AMD; + + return VENDOR_INVALID; +} + struct cpuInfo* getCPUInfo() { struct cpuInfo* cpu = malloc(sizeof(struct cpuInfo)); initializeCpuInfo(cpu); unsigned eax, ebx, ecx, edx; + //Get max cpuid level eax = 0x0000000; cpuid(&eax, &ebx, &ecx, &edx); cpu->maxLevels = eax; + //Fill vendor + cpu->cpu_vendor = getCPUVendor(eax,ebx,ecx,edx); + if(cpu->cpu_vendor == VENDOR_INVALID) { + printf("ERROR: CPU vendor is neither AMD nor INTEL\n"); + return NULL; + } + + //Get max extended level cpuid(&eax, &ebx, &ecx, &edx); cpu->maxExtendedLevels = eax; @@ -202,7 +242,10 @@ char* getPeakPerformance(struct cpuInfo* cpu, long freq) { return string; } -//4 cores(8 threads) +VENDOR getCPUVendorInternal(struct cpuInfo* cpu) { + return cpu->cpu_vendor; +} + char* getString_NumberCores(struct cpuInfo* cpu) { if(cpu->HT > 1) { //2(N.Cores)7(' cores(')2(N.Threads)9(' threads)') @@ -213,7 +256,7 @@ char* getString_NumberCores(struct cpuInfo* cpu) { } else { char* string = malloc(sizeof(char)*2+1); - snprintf(string,2+1,"%d cores",cpu->nThreads); + snprintf(string,2+7+1,"%d cores",cpu->nThreads); return string; } diff --git a/01h.h b/01h.h index 019c31a..3c64240 100644 --- a/01h.h +++ b/01h.h @@ -3,13 +3,24 @@ #define STRING_YES "Yes" #define STRING_NO "No" + +#define VENDOR_EMPTY 0 +#define VENDOR_INTEL 1 +#define VENDOR_AMD 2 +#define VENDOR_INVALID 3 +#define VENDOR_INTEL_STRING "GenuineIntel" +#define VENDOR_AMD_STRING "AuthenticAMD" +typedef int VENDOR; + struct cpuInfo; struct cpuInfo* getCPUInfo(); void debugCpuInfo(struct cpuInfo* cpu); -char* getString_NumberCores(struct cpuInfo* cpu); +VENDOR getCPUVendorInternal(struct cpuInfo* cpu); char* getPeakPerformance(struct cpuInfo* cpu, long freq); + +char* getString_NumberCores(struct cpuInfo* cpu); char* getString_AVX(struct cpuInfo* cpu); char* getString_SSE(struct cpuInfo* cpu); char* getString_FMA(struct cpuInfo* cpu); diff --git a/Makefile b/Makefile index b9bd684..6147acf 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,8 @@ CXX=gcc CXXFLAGS=-g -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 +SOURCE=main.c 01h.c 02h.c extended.c cpuid.c udev.c printer.c +HEADERS=01h.c 02h.h extended.h cpuid.h udev.h printer.h ascii.h OUTPUT=cpufetch diff --git a/ascii.h b/ascii.h new file mode 100644 index 0000000..43490a3 --- /dev/null +++ b/ascii.h @@ -0,0 +1,49 @@ +#ifndef __ASCII__ +#define __ASCII__ + +#define NUMBER_OF_LINES 20 +#define LINE_SIZE 63 + +#define AMD1 " \0" +#define AMD2 " \0" +#define AMD3 " \0" +#define AMD4 " \0" +#define AMD5 " \0" +#define AMD6 " \0" +#define AMD7 " @@@@ @@@% @@@. @@@@@@@@( .############ \0" +#define AMD8 " @@@@@@ @@@@@ %@@@@. @@@ @@@@ .((((((#### \0" +#define AMD9 " @@@ @@@ @@@/@@@@@@&@@. @@@ %@@% # #### \0" +#define AMD10 " @@@, (@@# @@@ @@@/ @@@. @@@ .@@@ ### #### \0" +#define AMD11 " ,@@@@@@@@@@, @@@ @@@. @@@ @@@ #### #### \0" +#define AMD12 " @@@ @@@ @@@ @@@. @@@@@@@@@& #######/ .## \0" +#define AMD13 " \0" +#define AMD14 " \0" +#define AMD15 " \0" +#define AMD16 " \0" +#define AMD17 " \0" +#define AMD18 " \0" +#define AMD19 " \0" +#define AMD20 " \0" + +#define INTEL1 " ################ \0" +#define INTEL2 " ####### ####### \0" +#define INTEL3 " #### #### \0" +#define INTEL4 " ### #### \0" +#define INTEL5 " ### ### \0" +#define INTEL6 " ### ### \0" +#define INTEL7 " # ### ### ### \0" +#define INTEL8 " ## ### ######### ###### ###### ### ### \0" +#define INTEL9 " ## ### ### ### ### #### #### ### ### \0" +#define INTEL10 " ## ### ### ### ### ### ### ### ### \0" +#define INTEL11 "## ### ### ### ### ########## ### #### \0" +#define INTEL12 "## ### ### ### ### ### ### ##### \0" +#define INTEL13 "## ## ### ### ##### ######### ## ### \0" +#define INTEL14 "### \0" +#define INTEL15 "(### \0" +#define INTEL16 " #### #### \0" +#define INTEL17 " ##### ########## \0" +#define INTEL18 " ########## ################ \0" +#define INTEL19 " ############################### \0" +#define INTEL20 " \0" + +#endif diff --git a/extended.c b/extended.c index 5714f34..eea4d38 100644 --- a/extended.c +++ b/extended.c @@ -1,17 +1,22 @@ +#include +#include #include "extended.h" char* getString_CPUName() { unsigned eax, ebx, ecx, edx; + char* name = malloc(sizeof(char)*64); + memset(name,0,64); //First, check we can use extended eax = 0x80000000; cpuid(&eax, &ebx, &ecx, &edx); - if(eax < 0x80000001) - return NULL; + if(eax < 0x80000001) { + sprintf(name,"Unknown"); + return name; + } + //We can, fetch name - char* name = malloc(sizeof(char)*64); - eax = 0x80000002; cpuid(&eax, &ebx, &ecx, &edx); diff --git a/main.c b/main.c index c4d3b65..c1f2238 100644 --- a/main.c +++ b/main.c @@ -26,8 +26,12 @@ Peak FLOPS: 512 GFLOP/s(in simple precision) int main() { struct cpuInfo* cpu = getCPUInfo(cpu); + if(cpu == NULL) + return EXIT_FAILURE; + struct cache* cach = new_cache(cach); struct frequency* freq = new_frequency(freq); + struct ascii* ascii = set_ascii(getCPUVendorInternal(cpu)); char* cpuName = getString_CPUName(); char* maxFrequency = getString_MaxFrequency(freq); @@ -41,20 +45,66 @@ int main() { char* l2 = getString_L2(cach); char* l3 = getString_L3(cach); + print_ascii(ascii,__COUNTER__); + printf("\n"); + + print_ascii(ascii,__COUNTER__); + printf("\n"); + + print_ascii(ascii,__COUNTER__); + printf("\n"); + + print_ascii(ascii,__COUNTER__); printf(TITLE_NAME"%s\n",cpuName); + + print_ascii(ascii,__COUNTER__); printf(TITLE_ARCH"%s\n","x86_64"); + + print_ascii(ascii,__COUNTER__); printf(TITLE_FREQUENCY"%s\n",maxFrequency); + + print_ascii(ascii,__COUNTER__); printf(TITLE_NCORES"%s\n",nCores); + + print_ascii(ascii,__COUNTER__); printf(TITLE_AVX"%s\n",avx); + + print_ascii(ascii,__COUNTER__); printf(TITLE_SSE"%s\n",sse); + + print_ascii(ascii,__COUNTER__); printf(TITLE_FMA"%s\n",fma); + + print_ascii(ascii,__COUNTER__); printf(TITLE_AES"%s\n",aes); + + print_ascii(ascii,__COUNTER__); printf(TITLE_SHA"%s\n",sha); + + print_ascii(ascii,__COUNTER__); printf(TITLE_L1"%s\n",l1); + + print_ascii(ascii,__COUNTER__); printf(TITLE_L2"%s\n",l2); + + print_ascii(ascii,__COUNTER__); printf(TITLE_L3"%s\n",l3); + + print_ascii(ascii,__COUNTER__); printf(TITLE_PEAK"%s\n",getPeakPerformance(cpu,getFrequency(freq))); + print_ascii(ascii,__COUNTER__); + printf("\n"); + + print_ascii(ascii,__COUNTER__); + printf("\n"); + + print_ascii(ascii,__COUNTER__); + printf("\n"); + + print_ascii(ascii,__COUNTER__); + printf("\n"); + free(cpuName); free(maxFrequency); free(nCores); diff --git a/printer.c b/printer.c new file mode 100644 index 0000000..aef7768 --- /dev/null +++ b/printer.c @@ -0,0 +1,63 @@ +#include +#include +#include + +#include "printer.h" +#include "ascii.h" + +struct ascii { + char art[NUMBER_OF_LINES][LINE_SIZE]; +}; + +struct ascii* set_ascii(VENDOR cpuVendor) { + struct ascii* art = malloc(sizeof(struct ascii)); + if(cpuVendor == VENDOR_INTEL) { + strcpy(art->art[0],INTEL1); + strcpy(art->art[1],INTEL2); + strcpy(art->art[2],INTEL3); + strcpy(art->art[3],INTEL4); + strcpy(art->art[4],INTEL5); + strcpy(art->art[5],INTEL6); + strcpy(art->art[6],INTEL7); + strcpy(art->art[7],INTEL8); + strcpy(art->art[8],INTEL9); + strcpy(art->art[9],INTEL10); + strcpy(art->art[10],INTEL11); + strcpy(art->art[11],INTEL12); + strcpy(art->art[12],INTEL13); + strcpy(art->art[13],INTEL14); + strcpy(art->art[14],INTEL15); + strcpy(art->art[15],INTEL16); + strcpy(art->art[16],INTEL17); + strcpy(art->art[17],INTEL18); + strcpy(art->art[18],INTEL19); + strcpy(art->art[19],INTEL20); + } + else { + strcpy(art->art[0],AMD1); + strcpy(art->art[1],AMD2); + strcpy(art->art[2],AMD3); + strcpy(art->art[3],AMD4); + strcpy(art->art[4],AMD5); + strcpy(art->art[5],AMD6); + strcpy(art->art[6],AMD7); + strcpy(art->art[7],AMD8); + strcpy(art->art[8],AMD9); + strcpy(art->art[9],AMD10); + strcpy(art->art[10],AMD11); + strcpy(art->art[11],AMD12); + strcpy(art->art[12],AMD13); + strcpy(art->art[13],AMD14); + strcpy(art->art[14],AMD15); + strcpy(art->art[15],AMD16); + strcpy(art->art[16],AMD17); + strcpy(art->art[17],AMD18); + strcpy(art->art[18],AMD19); + strcpy(art->art[19],AMD20); + } + return art; +} + +void print_ascii(struct ascii* art, int n) { + printf("%s",art->art[n]); +} diff --git a/printer.h b/printer.h index f6f9e2c..41dc9ea 100644 --- a/printer.h +++ b/printer.h @@ -1,22 +1,26 @@ #ifndef __PRINTER__ #define __PRINTER__ -//#include "ascii.h" +#include "01h.h" +#include "ascii.h" -//void print_ascii(int n); +struct ascii; -#define TITLE_NAME "Name: " -#define TITLE_ARCH "Arch: " -#define TITLE_FREQUENCY "Frequency: " -#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: " +struct ascii* set_ascii(VENDOR cpuVendor); +void print_ascii(struct ascii* art, int n); + +#define TITLE_NAME "Name: " +#define TITLE_ARCH "Arch: " +#define TITLE_FREQUENCY "Frequency: " +#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