mirror of
https://github.com/Dr-Noob/cpufetch.git
synced 2026-03-26 00:10:38 +01:00
Print total cache sizes (for L1 and L2, but also for L3 in case we run in dual socket!)
This commit is contained in:
48
src/main.c
48
src/main.c
@@ -8,24 +8,29 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
/***
|
/***
|
||||||
SAMPLE OUTPUT
|
################
|
||||||
|
####### #######
|
||||||
Name: Intel Core i7-4790K
|
#### ####
|
||||||
Frequency: 4.0 GHz
|
### ####
|
||||||
NºCores: 4 cores(8 threads)
|
### ### Name: Intel(R) Xeon(R) CPU E5-2698 v4 @ 2.20GHz
|
||||||
AXV: AVX,AVX2
|
### ### Sockets: 2
|
||||||
SSE: SSE,SSE2,SSE4.1,SSE4.2
|
Cores: 20 (40 threads)
|
||||||
FMA: FMA3
|
Frequency: 3.60 GHz
|
||||||
AES: Yes
|
## ### ######### ###### ###### ### ### AVX: AVX,AVX2
|
||||||
SHA: No
|
## ### ### ### ### #### #### ### ### SSE: SSE,SSE2,SSE3,SSSE3,SSE4_1,SSE4_2
|
||||||
L1 Size: 32KB(Data)32KB(Instructions)
|
## ### ### ### ### ### ### ### ### FMA: FMA3
|
||||||
L2 Size: 512KB
|
## ## ### ### ##### ######### ## ### L1d Size: 32KB (1MB Total)
|
||||||
L3 Size: 8MB
|
## ## L1i Size: 32KB (1MB Total)
|
||||||
Peak FLOPS: 512 GFLOP/s(in simple precision)
|
### L2 Size: 256KB (4MB Total)
|
||||||
|
### L3 Size: 50M (100MB Total)
|
||||||
|
#### #### Peak Perf.: 2.30 TFLOP/s
|
||||||
|
##### ##########
|
||||||
|
########## ################
|
||||||
|
###############################
|
||||||
|
|
||||||
***/
|
***/
|
||||||
|
|
||||||
static const char* VERSION = "0.410";
|
static const char* VERSION = "0.411";
|
||||||
|
|
||||||
void print_help(char *argv[]) {
|
void print_help(char *argv[]) {
|
||||||
printf("Usage: %s [--version] [--help] [--style STYLE]\n\
|
printf("Usage: %s [--version] [--help] [--style STYLE]\n\
|
||||||
@@ -94,9 +99,10 @@ int main(int argc, char* argv[]) {
|
|||||||
char* fma = get_str_fma(cpu);
|
char* fma = get_str_fma(cpu);
|
||||||
char* aes = get_str_aes(cpu);
|
char* aes = get_str_aes(cpu);
|
||||||
char* sha = get_str_sha(cpu);
|
char* sha = get_str_sha(cpu);
|
||||||
char* l1 = get_str_l1(cach);
|
char* l1i = get_str_l1i(cach, topo);
|
||||||
char* l2 = get_str_l2(cach);
|
char* l1d = get_str_l1d(cach, topo);
|
||||||
char* l3 = get_str_l3(cach);
|
char* l2 = get_str_l2(cach, topo);
|
||||||
|
char* l3 = get_str_l3(cach, topo);
|
||||||
char* pp = get_str_peak_performance(cpu,topo,get_freq(freq));
|
char* pp = get_str_peak_performance(cpu,topo,get_freq(freq));
|
||||||
|
|
||||||
setAttribute(art,ATTRIBUTE_NAME,cpuName);
|
setAttribute(art,ATTRIBUTE_NAME,cpuName);
|
||||||
@@ -107,7 +113,8 @@ int main(int argc, char* argv[]) {
|
|||||||
setAttribute(art,ATTRIBUTE_FMA,fma);
|
setAttribute(art,ATTRIBUTE_FMA,fma);
|
||||||
setAttribute(art,ATTRIBUTE_AES,aes);
|
setAttribute(art,ATTRIBUTE_AES,aes);
|
||||||
setAttribute(art,ATTRIBUTE_SHA,sha);
|
setAttribute(art,ATTRIBUTE_SHA,sha);
|
||||||
setAttribute(art,ATTRIBUTE_L1,l1);
|
setAttribute(art,ATTRIBUTE_L1i,l1i);
|
||||||
|
setAttribute(art,ATTRIBUTE_L1d,l1d);
|
||||||
setAttribute(art,ATTRIBUTE_L2,l2);
|
setAttribute(art,ATTRIBUTE_L2,l2);
|
||||||
setAttribute(art,ATTRIBUTE_L3,l3);
|
setAttribute(art,ATTRIBUTE_L3,l3);
|
||||||
setAttribute(art,ATTRIBUTE_PEAK,pp);
|
setAttribute(art,ATTRIBUTE_PEAK,pp);
|
||||||
@@ -122,7 +129,8 @@ int main(int argc, char* argv[]) {
|
|||||||
free(fma);
|
free(fma);
|
||||||
free(aes);
|
free(aes);
|
||||||
free(sha);
|
free(sha);
|
||||||
free(l1);
|
free(l1i);
|
||||||
|
free(l1d);
|
||||||
free(l2);
|
free(l2);
|
||||||
free(l3);
|
free(l3);
|
||||||
free(pp);
|
free(pp);
|
||||||
|
|||||||
@@ -26,25 +26,26 @@
|
|||||||
#define TITLE_FMA "FMA: "
|
#define TITLE_FMA "FMA: "
|
||||||
#define TITLE_AES "AES: "
|
#define TITLE_AES "AES: "
|
||||||
#define TITLE_SHA "SHA: "
|
#define TITLE_SHA "SHA: "
|
||||||
#define TITLE_L1 "L1 Size: "
|
#define TITLE_L1i "L1i Size: "
|
||||||
|
#define TITLE_L1d "L1d Size: "
|
||||||
#define TITLE_L2 "L2 Size: "
|
#define TITLE_L2 "L2 Size: "
|
||||||
#define TITLE_L3 "L3 Size: "
|
#define TITLE_L3 "L3 Size: "
|
||||||
#define TITLE_PEAK "Peak FLOPS: "
|
#define TITLE_PEAK "Peak FLOPS: "
|
||||||
|
|
||||||
/*** CENTER TEXT ***/
|
/*** CENTER TEXT ***/
|
||||||
#define LINES_SPACE_UP 4
|
#define LINES_SPACE_UP 3
|
||||||
#define LINES_SPACE_DOWN 4
|
#define LINES_SPACE_DOWN 4
|
||||||
|
|
||||||
static const char* ATTRIBUTE_FIELDS [ATTRIBUTE_COUNT] = { TITLE_NAME, TITLE_FREQUENCY,
|
static const char* ATTRIBUTE_FIELDS [ATTRIBUTE_COUNT] = { TITLE_NAME, TITLE_FREQUENCY,
|
||||||
TITLE_NCORES, TITLE_AVX, TITLE_SSE,
|
TITLE_NCORES, TITLE_AVX, TITLE_SSE,
|
||||||
TITLE_FMA, TITLE_AES, TITLE_SHA,
|
TITLE_FMA, TITLE_AES, TITLE_SHA,
|
||||||
TITLE_L1, TITLE_L2, TITLE_L3,
|
TITLE_L1i, TITLE_L1d, TITLE_L2, TITLE_L3,
|
||||||
TITLE_PEAK };
|
TITLE_PEAK };
|
||||||
|
|
||||||
static const int ATTRIBUTE_LIST[ATTRIBUTE_COUNT] = { ATTRIBUTE_NAME, ATTRIBUTE_FREQUENCY,
|
static const int ATTRIBUTE_LIST[ATTRIBUTE_COUNT] = { ATTRIBUTE_NAME, ATTRIBUTE_FREQUENCY,
|
||||||
ATTRIBUTE_NCORES, ATTRIBUTE_AVX, ATTRIBUTE_SSE,
|
ATTRIBUTE_NCORES, ATTRIBUTE_AVX, ATTRIBUTE_SSE,
|
||||||
ATTRIBUTE_FMA, ATTRIBUTE_AES, ATTRIBUTE_SHA,
|
ATTRIBUTE_FMA, ATTRIBUTE_AES, ATTRIBUTE_SHA,
|
||||||
ATTRIBUTE_L1, ATTRIBUTE_L2, ATTRIBUTE_L3,
|
ATTRIBUTE_L1i, ATTRIBUTE_L1d, ATTRIBUTE_L2, ATTRIBUTE_L3,
|
||||||
ATTRIBUTE_PEAK };
|
ATTRIBUTE_PEAK };
|
||||||
|
|
||||||
struct ascii {
|
struct ascii {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include "standart.h"
|
#include "standart.h"
|
||||||
#include "ascii.h"
|
#include "ascii.h"
|
||||||
|
|
||||||
#define ATTRIBUTE_COUNT 12
|
#define ATTRIBUTE_COUNT 13
|
||||||
#define ATTRIBUTE_NAME 0
|
#define ATTRIBUTE_NAME 0
|
||||||
#define ATTRIBUTE_FREQUENCY 1
|
#define ATTRIBUTE_FREQUENCY 1
|
||||||
#define ATTRIBUTE_NCORES 2
|
#define ATTRIBUTE_NCORES 2
|
||||||
@@ -13,10 +13,11 @@
|
|||||||
#define ATTRIBUTE_FMA 5
|
#define ATTRIBUTE_FMA 5
|
||||||
#define ATTRIBUTE_AES 6
|
#define ATTRIBUTE_AES 6
|
||||||
#define ATTRIBUTE_SHA 7
|
#define ATTRIBUTE_SHA 7
|
||||||
#define ATTRIBUTE_L1 8
|
#define ATTRIBUTE_L1i 8
|
||||||
#define ATTRIBUTE_L2 9
|
#define ATTRIBUTE_L1d 9
|
||||||
#define ATTRIBUTE_L3 10
|
#define ATTRIBUTE_L2 10
|
||||||
#define ATTRIBUTE_PEAK 11
|
#define ATTRIBUTE_L3 11
|
||||||
|
#define ATTRIBUTE_PEAK 12
|
||||||
|
|
||||||
typedef int STYLE;
|
typedef int STYLE;
|
||||||
#define STYLES_COUNT 3
|
#define STYLES_COUNT 3
|
||||||
|
|||||||
136
src/standart.c
136
src/standart.c
@@ -1,6 +1,5 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@@ -202,6 +201,7 @@ struct cpuInfo* get_cpu_info() {
|
|||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 80/2/20
|
||||||
struct topology* get_topology_info(struct cpuInfo* cpu) {
|
struct topology* get_topology_info(struct cpuInfo* cpu) {
|
||||||
struct topology* topo = malloc(sizeof(struct topology));
|
struct topology* topo = malloc(sizeof(struct topology));
|
||||||
uint32_t eax = 0;
|
uint32_t eax = 0;
|
||||||
@@ -223,7 +223,6 @@ struct topology* get_topology_info(struct cpuInfo* cpu) {
|
|||||||
switch(cpu->cpu_vendor) {
|
switch(cpu->cpu_vendor) {
|
||||||
case VENDOR_INTEL:
|
case VENDOR_INTEL:
|
||||||
if (cpu->maxLevels >= 0x0000000B) {
|
if (cpu->maxLevels >= 0x0000000B) {
|
||||||
//TODO: This idea only works with no NUMA systems
|
|
||||||
eax = 0x0000000B;
|
eax = 0x0000000B;
|
||||||
ecx = 0x00000000;
|
ecx = 0x00000000;
|
||||||
cpuid(&eax, &ebx, &ecx, &edx);
|
cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
@@ -640,67 +639,110 @@ char* get_str_sha(struct cpuInfo* cpu) {
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// String functions
|
int32_t get_value_as_smallest_unit(char ** str, uint32_t value) {
|
||||||
char* get_str_l1(struct cache* cach) {
|
|
||||||
// 2*2 for digits, 4 for two 'KB' and 6 for '(D)' and '(I)'
|
|
||||||
uint32_t size = (2*2+4+6+1);
|
|
||||||
int32_t sanity_ret;
|
int32_t sanity_ret;
|
||||||
char* string = malloc(sizeof(char)*size);
|
*str = malloc(sizeof(char)* 7); //4 for digits, 2 for units
|
||||||
sanity_ret = snprintf(string,size,"%d"STRING_KILOBYTES"(D)%d"STRING_KILOBYTES"(I)",cach->L1d/1024,cach->L1i/1024);
|
|
||||||
assert(sanity_ret > 0);
|
if(value/1024 >= 1024)
|
||||||
|
sanity_ret = snprintf(*str, 6,"%d"STRING_MEGABYTES,value/(1<<20));
|
||||||
|
else
|
||||||
|
sanity_ret = snprintf(*str, 6,"%d"STRING_KILOBYTES,value/(1<<10));
|
||||||
|
|
||||||
|
return sanity_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// String functions
|
||||||
|
char* get_str_cache_two(int32_t cache_size, uint32_t physical_cores) {
|
||||||
|
// 4 for digits, 2 for units, 2 for ' (', 3 digits, 2 for units and 7 for ' Total)'
|
||||||
|
uint32_t max_size = 4+2 + 2 + 4+2 + 7 + 1;
|
||||||
|
int32_t sanity_ret;
|
||||||
|
char* string = malloc(sizeof(char) * max_size);
|
||||||
|
char* tmp1;
|
||||||
|
char* tmp2;
|
||||||
|
int32_t tmp1_len = get_value_as_smallest_unit(&tmp1, cache_size);
|
||||||
|
int32_t tmp2_len = get_value_as_smallest_unit(&tmp2, cache_size * physical_cores);
|
||||||
|
|
||||||
|
if(tmp1_len < 0) {
|
||||||
|
printBug("get_value_as_smallest_unit: snprintf returned a negative value for input: %d\n", cache_size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(tmp2_len < 0) {
|
||||||
|
printBug("get_value_as_smallest_unit: snprintf returned a negative value for input: %d\n", cache_size * physical_cores);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t size = tmp1_len + 2 + tmp2_len + 7 + 1;
|
||||||
|
sanity_ret = snprintf(string, size, "%s (%s Total)", tmp1, tmp2);
|
||||||
|
|
||||||
|
if(sanity_ret < 0) {
|
||||||
|
printBug("get_str_cache_two: snprintf returned a negative value for input: '%s' and '%s'\n", tmp1, tmp2);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(tmp1);
|
||||||
|
free(tmp2);
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* get_str_l2(struct cache* cach) {
|
char* get_str_cache_one(int32_t cache_size) {
|
||||||
|
// 4 for digits, 2 for units, 2 for ' (', 3 digits, 2 for units and 7 for ' Total)'
|
||||||
|
uint32_t max_size = 4+2 + 1;
|
||||||
|
int32_t sanity_ret;
|
||||||
|
char* string = malloc(sizeof(char) * max_size);
|
||||||
|
char* tmp;
|
||||||
|
int32_t tmp_len = get_value_as_smallest_unit(&tmp, cache_size);
|
||||||
|
|
||||||
|
if(tmp_len < 0) {
|
||||||
|
printBug("get_value_as_smallest_unit: snprintf returned a negative value for input: %d\n", cache_size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t size = tmp_len + 1;
|
||||||
|
sanity_ret = snprintf(string, size, "%s", tmp);
|
||||||
|
|
||||||
|
if(sanity_ret < 0) {
|
||||||
|
printBug("get_str_cache_one: snprintf returned a negative value for input: '%s'\n", tmp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
free(tmp);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* get_str_cache(int32_t cache_size, struct topology* topo, bool llc) {
|
||||||
|
if(llc) {
|
||||||
|
if(topo->sockets == 1)
|
||||||
|
return get_str_cache_one(cache_size);
|
||||||
|
else
|
||||||
|
return get_str_cache_two(cache_size, topo->sockets);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return get_str_cache_two(cache_size, topo->physical_cores);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* get_str_l1i(struct cache* cach, struct topology* topo) {
|
||||||
|
return get_str_cache(cach->L1i, topo, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* get_str_l1d(struct cache* cach, struct topology* topo) {
|
||||||
|
return get_str_cache(cach->L1d, topo, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* get_str_l2(struct cache* cach, struct topology* topo) {
|
||||||
if(cach->L2 == UNKNOWN) {
|
if(cach->L2 == UNKNOWN) {
|
||||||
char* string = malloc(sizeof(char) * 5);
|
char* string = malloc(sizeof(char) * 5);
|
||||||
snprintf(string, 5, STRING_NONE);
|
snprintf(string, 5, STRING_NONE);
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
else {
|
return get_str_cache(cach->L2, topo, false);
|
||||||
int32_t sanity_ret;
|
|
||||||
char* string;
|
|
||||||
if(cach->L2/1024 >= 1024) {
|
|
||||||
//1 for digit, 2 for 'MB'
|
|
||||||
uint32_t size = (1+2+1);
|
|
||||||
string = malloc(sizeof(char)*size);
|
|
||||||
sanity_ret = snprintf(string,size,"%d"STRING_MEGABYTES,cach->L2/(1048576));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//4 for digits, 2 for 'KB'
|
|
||||||
uint32_t size = (4+2+1);
|
|
||||||
string = malloc(sizeof(char)*size);
|
|
||||||
sanity_ret = snprintf(string,size,"%d"STRING_KILOBYTES,cach->L2/1024);
|
|
||||||
}
|
|
||||||
assert(sanity_ret > 0);
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* get_str_l3(struct cache* cach) {
|
char* get_str_l3(struct cache* cach, struct topology* topo) {
|
||||||
if(cach->L3 == UNKNOWN) {
|
if(cach->L3 == UNKNOWN) {
|
||||||
char* string = malloc(sizeof(char) * 5);
|
char* string = malloc(sizeof(char) * 5);
|
||||||
snprintf(string, 5, STRING_NONE);
|
snprintf(string, 5, STRING_NONE);
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
else {
|
return get_str_cache(cach->L3, topo, true);
|
||||||
int32_t sanity_ret;
|
|
||||||
char* string;
|
|
||||||
if(cach->L3/1024 >= 1024) {
|
|
||||||
//1 for digit, 2 for 'MB'
|
|
||||||
uint32_t size = (1+2+1);
|
|
||||||
string = malloc(sizeof(char)*size);
|
|
||||||
sanity_ret = snprintf(string,size,"%d"STRING_MEGABYTES,cach->L3/(1048576));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//4 for digits, 2 for 'KB'
|
|
||||||
uint32_t size = (4+2+1);
|
|
||||||
string = malloc(sizeof(char)*size);
|
|
||||||
sanity_ret = snprintf(string,size,"%d"STRING_KILOBYTES,cach->L3/1024);
|
|
||||||
}
|
|
||||||
assert(sanity_ret > 0);
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* get_str_freq(struct frequency* freq) {
|
char* get_str_freq(struct frequency* freq) {
|
||||||
|
|||||||
@@ -31,9 +31,10 @@ char* get_str_fma(struct cpuInfo* cpu);
|
|||||||
char* get_str_aes(struct cpuInfo* cpu);
|
char* get_str_aes(struct cpuInfo* cpu);
|
||||||
char* get_str_sha(struct cpuInfo* cpu);
|
char* get_str_sha(struct cpuInfo* cpu);
|
||||||
|
|
||||||
char* get_str_l1(struct cache* cach);
|
char* get_str_l1i(struct cache* cach, struct topology* topo);
|
||||||
char* get_str_l2(struct cache* cach);
|
char* get_str_l1d(struct cache* cach, struct topology* topo);
|
||||||
char* get_str_l3(struct cache* cach);
|
char* get_str_l2(struct cache* cach, struct topology* topo);
|
||||||
|
char* get_str_l3(struct cache* cach, struct topology* topo);
|
||||||
|
|
||||||
char* get_str_freq(struct frequency* freq);
|
char* get_str_freq(struct frequency* freq);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user