Print all information

This commit is contained in:
Dr-Noob
2018-03-29 23:27:59 +02:00
parent 4ebcfbeed3
commit 978f283e1a
10 changed files with 409 additions and 15 deletions

103
01h.c
View File

@@ -1,5 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include "01h.h" #include "01h.h"
#include "cpuid.h" #include "cpuid.h"
@@ -36,6 +38,7 @@ struct cpuInfo {
int AES; int AES;
int SHA; int SHA;
int nCores;
int maxLevels; int maxLevels;
int maxExtendedLevels; int maxExtendedLevels;
}; };
@@ -61,6 +64,7 @@ struct cpuInfo* getCPUInfo() {
struct cpuInfo* cpu = malloc(sizeof(struct cpuInfo)); struct cpuInfo* cpu = malloc(sizeof(struct cpuInfo));
initializeCpuInfo(cpu); initializeCpuInfo(cpu);
cpu->nCores = sysconf( _SC_NPROCESSORS_ONLN );
unsigned eax, ebx, ecx, edx; unsigned eax, ebx, ecx, edx;
eax = 0x0000000; eax = 0x0000000;
cpuid(&eax, &ebx, &ecx, &edx); cpuid(&eax, &ebx, &ecx, &edx);
@@ -88,6 +92,7 @@ struct cpuInfo* getCPUInfo() {
} }
if (cpu->maxLevels >= 0x00000007){ if (cpu->maxLevels >= 0x00000007){
eax = 0x00000007; eax = 0x00000007;
ecx = 0x00000000;
cpuid(&eax, &ebx, &ecx, &edx); cpuid(&eax, &ebx, &ecx, &edx);
cpu->AVX2 = (ebx & ((int)1 << 5)) != 0; cpu->AVX2 = (ebx & ((int)1 << 5)) != 0;
cpu->SHA = (ebx & ((int)1 << 29)) != 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("AES=%s\n", cpu->AES ? "true" : "false");
printf("SHA=%s\n", cpu->SHA ? "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;
}

8
01h.h
View File

@@ -2,7 +2,15 @@
#define __01h__ #define __01h__
struct cpuInfo; struct cpuInfo;
struct cpuInfo* getCPUInfo(); struct cpuInfo* getCPUInfo();
void debugCpuInfo(struct cpuInfo* cpu); 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 #endif

4
02h.c
View File

@@ -359,7 +359,7 @@ struct level2* fillLevel2(struct level2* data) {
return data; return data;
} }
void debugCache(struct cache* cach) { void debugCachex(struct cache* cach) {
printf("L1d=%d\n", cach->L1d); printf("L1d=%d\n", cach->L1d);
printf("L1i=%d\n", cach->L1i); printf("L1i=%d\n", cach->L1i);
printf("L2=%d\n", cach->L2); printf("L2=%d\n", cach->L2);
@@ -372,7 +372,7 @@ void debugTLB(struct TLB* tlb) {
} }
void debugLevel2(struct level2* data) { void debugLevel2(struct level2* data) {
debugCache(data->cache); debugCachex(data->cache);
debugTLB(data->tlb); debugTLB(data->tlb);
} }

View File

@@ -2,13 +2,15 @@ CXX=gcc
CXXFLAGS=-g CXXFLAGS=-g
SOURCE=main.c 01h.c 02h.c extended.c cpuid.c SOURCE=main.c 01h.c 02h.c extended.c cpuid.c udev.c
HEADERS=01h.c 02h.h extended.h cpuid.h HEADERS=01h.c 02h.h extended.h cpuid.h udev.h printer.h
OUTPUT=cpufetch OUTPUT=cpufetch
$(OUTPUT): Makefile $(SOURCE) $(HEADERS) $(OUTPUT): Makefile $(SOURCE) $(HEADERS)
$(CXX) $(CXXFLAGS) $(SOURCE) -o $(OUTPUT) $(CXX) $(CXXFLAGS) $(SOURCE) -o $(OUTPUT)
run:
./$(OUTPUT)
clean: clean:
@rm $(OUTPUT1) $(OUTPUT2) @rm $(OUTPUT)

View File

@@ -1,6 +1,6 @@
#include "extended.h" #include "extended.h"
char* getCPUName() { char* getString_CPUName() {
unsigned eax, ebx, ecx, edx; unsigned eax, ebx, ecx, edx;
//First, check we can use extended //First, check we can use extended

View File

@@ -5,6 +5,6 @@
#include "cpuid.h" #include "cpuid.h"
#include <stdlib.h> #include <stdlib.h>
char* getCPUName(); char* getString_CPUName();
#endif #endif

54
main.c
View File

@@ -1,7 +1,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "printer.h"
#include "01h.h" #include "01h.h"
#include "02h.h" #include "udev.h"
#include "extended.h" #include "extended.h"
/*** /***
@@ -24,13 +25,50 @@ Peak FLOPS: 512 GFLOP/s(in simple precision)
***/ ***/
int main() { int main() {
struct level2* level2 = fillLevel2(level2);
debugLevel2(level2);
freeLevel2(level2);
struct cpuInfo* cpu = getCPUInfo(cpu); struct cpuInfo* cpu = getCPUInfo(cpu);
debugCpuInfo(cpu); struct cache* cach = new_cache(cach);
free(cpu); 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());
} }

22
printer.h Normal file
View File

@@ -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

177
udev.c Normal file
View File

@@ -0,0 +1,177 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#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);
}

44
udev.h Normal file
View File

@@ -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