1
0
Fork 0
mirror of https://github.com/anrieff/libcpuid synced 2024-12-16 16:35:45 +00:00

Add detection of L4 cache.

This commit is contained in:
Veselin Georgiev 2016-06-09 15:42:57 +03:00
parent 571fe75d88
commit 3f51d3ca25
4 changed files with 44 additions and 8 deletions

View file

@ -72,12 +72,15 @@ typedef enum {
NEED_L1I_SIZE, NEED_L1I_SIZE,
NEED_L2_SIZE, NEED_L2_SIZE,
NEED_L3_SIZE, NEED_L3_SIZE,
NEED_L4_SIZE,
NEED_L1D_ASSOC, NEED_L1D_ASSOC,
NEED_L2_ASSOC, NEED_L2_ASSOC,
NEED_L3_ASSOC, NEED_L3_ASSOC,
NEED_L4_ASSOC,
NEED_L1D_CACHELINE, NEED_L1D_CACHELINE,
NEED_L2_CACHELINE, NEED_L2_CACHELINE,
NEED_L3_CACHELINE, NEED_L3_CACHELINE,
NEED_L4_CACHELINE,
NEED_CODENAME, NEED_CODENAME,
NEED_FEATURES, NEED_FEATURES,
NEED_CLOCK, NEED_CLOCK,
@ -124,12 +127,15 @@ matchtable[] = {
{ NEED_L2_SIZE , "--cache" , 1}, { NEED_L2_SIZE , "--cache" , 1},
{ NEED_L2_SIZE , "--l2-cache" , 1}, { NEED_L2_SIZE , "--l2-cache" , 1},
{ NEED_L3_SIZE , "--l3-cache" , 1}, { NEED_L3_SIZE , "--l3-cache" , 1},
{ NEED_L4_SIZE , "--l4-cache" , 1},
{ NEED_L1D_ASSOC , "--l1d-assoc" , 1}, { NEED_L1D_ASSOC , "--l1d-assoc" , 1},
{ NEED_L2_ASSOC , "--l2-assoc" , 1}, { NEED_L2_ASSOC , "--l2-assoc" , 1},
{ NEED_L3_ASSOC , "--l3-assoc" , 1}, { NEED_L3_ASSOC , "--l3-assoc" , 1},
{ NEED_L4_ASSOC , "--l4-assoc" , 1},
{ NEED_L1D_CACHELINE, "--l1d-cacheline", 1}, { NEED_L1D_CACHELINE, "--l1d-cacheline", 1},
{ NEED_L2_CACHELINE , "--l2-cacheline" , 1}, { NEED_L2_CACHELINE , "--l2-cacheline" , 1},
{ NEED_L3_CACHELINE , "--l3-cacheline" , 1}, { NEED_L3_CACHELINE , "--l3-cacheline" , 1},
{ NEED_L4_CACHELINE , "--l4-cacheline" , 1},
{ NEED_CODENAME , "--codename" , 1}, { NEED_CODENAME , "--codename" , 1},
{ NEED_FEATURES , "--flags" , 1}, { NEED_FEATURES , "--flags" , 1},
{ NEED_CLOCK , "--clock" , 0}, { NEED_CLOCK , "--clock" , 0},
@ -370,6 +376,9 @@ static void print_info(output_data_switch query, struct cpu_raw_data_t* raw,
case NEED_L3_SIZE: case NEED_L3_SIZE:
fprintf(fout, "%d\n", data->l3_cache); fprintf(fout, "%d\n", data->l3_cache);
break; break;
case NEED_L4_SIZE:
fprintf(fout, "%d\n", data->l4_cache);
break;
case NEED_L1D_ASSOC: case NEED_L1D_ASSOC:
fprintf(fout, "%d\n", data->l1_assoc); fprintf(fout, "%d\n", data->l1_assoc);
break; break;
@ -379,6 +388,9 @@ static void print_info(output_data_switch query, struct cpu_raw_data_t* raw,
case NEED_L3_ASSOC: case NEED_L3_ASSOC:
fprintf(fout, "%d\n", data->l3_assoc); fprintf(fout, "%d\n", data->l3_assoc);
break; break;
case NEED_L4_ASSOC:
fprintf(fout, "%d\n", data->l4_assoc);
break;
case NEED_L1D_CACHELINE: case NEED_L1D_CACHELINE:
fprintf(fout, "%d\n", data->l1_cacheline); fprintf(fout, "%d\n", data->l1_cacheline);
break; break;
@ -388,6 +400,9 @@ static void print_info(output_data_switch query, struct cpu_raw_data_t* raw,
case NEED_L3_CACHELINE: case NEED_L3_CACHELINE:
fprintf(fout, "%d\n", data->l3_cacheline); fprintf(fout, "%d\n", data->l3_cacheline);
break; break;
case NEED_L4_CACHELINE:
fprintf(fout, "%d\n", data->l4_cacheline);
break;
case NEED_CODENAME: case NEED_CODENAME:
fprintf(fout, "%s\n", data->cpu_codename); fprintf(fout, "%s\n", data->cpu_codename);
break; break;
@ -594,12 +609,15 @@ int main(int argc, char** argv)
fprintf(fout, " L1 I cache : %d KB\n", data.l1_instruction_cache); fprintf(fout, " L1 I cache : %d KB\n", data.l1_instruction_cache);
fprintf(fout, " L2 cache : %d KB\n", data.l2_cache); fprintf(fout, " L2 cache : %d KB\n", data.l2_cache);
fprintf(fout, " L3 cache : %d KB\n", data.l3_cache); fprintf(fout, " L3 cache : %d KB\n", data.l3_cache);
fprintf(fout, " L4 cache : %d KB\n", data.l4_cache);
fprintf(fout, " L1D assoc. : %d-way\n", data.l1_assoc); fprintf(fout, " L1D assoc. : %d-way\n", data.l1_assoc);
fprintf(fout, " L2 assoc. : %d-way\n", data.l2_assoc); fprintf(fout, " L2 assoc. : %d-way\n", data.l2_assoc);
fprintf(fout, " L3 assoc. : %d-way\n", data.l3_assoc); fprintf(fout, " L3 assoc. : %d-way\n", data.l3_assoc);
fprintf(fout, " L4 assoc. : %d-way\n", data.l4_assoc);
fprintf(fout, " L1D line sz: %d bytes\n", data.l1_cacheline); fprintf(fout, " L1D line sz: %d bytes\n", data.l1_cacheline);
fprintf(fout, " L2 line sz : %d bytes\n", data.l2_cacheline); fprintf(fout, " L2 line sz : %d bytes\n", data.l2_cacheline);
fprintf(fout, " L3 line sz : %d bytes\n", data.l3_cacheline); fprintf(fout, " L3 line sz : %d bytes\n", data.l3_cacheline);
fprintf(fout, " L4 line sz : %d bytes\n", data.l4_cacheline);
fprintf(fout, " SSE units : %d bits (%s)\n", data.sse_size, data.detection_hints[CPU_HINT_SSE_SIZE_AUTH] ? "authoritative" : "non-authoritative"); fprintf(fout, " SSE units : %d bits (%s)\n", data.sse_size, data.detection_hints[CPU_HINT_SSE_SIZE_AUTH] ? "authoritative" : "non-authoritative");
fprintf(fout, " code name : `%s'\n", data.cpu_codename); fprintf(fout, " code name : `%s'\n", data.cpu_codename);
fprintf(fout, " features :"); fprintf(fout, " features :");

View file

@ -54,9 +54,9 @@ static void raw_data_t_constructor(struct cpu_raw_data_t* raw)
static void cpu_id_t_constructor(struct cpu_id_t* id) static void cpu_id_t_constructor(struct cpu_id_t* id)
{ {
memset(id, 0, sizeof(struct cpu_id_t)); memset(id, 0, sizeof(struct cpu_id_t));
id->l1_data_cache = id->l1_instruction_cache = id->l2_cache = id->l3_cache = -1; id->l1_data_cache = id->l1_instruction_cache = id->l2_cache = id->l3_cache = id->l4_cache = -1;
id->l1_assoc = id->l2_assoc = id->l3_assoc = -1; id->l1_assoc = id->l2_assoc = id->l3_assoc = id->l4_assoc = -1;
id->l1_cacheline = id->l2_cacheline = id->l3_cacheline = -1; id->l1_cacheline = id->l2_cacheline = id->l3_cacheline = id->l4_cacheline = -1;
id->sse_size = -1; id->sse_size = -1;
} }
@ -460,10 +460,10 @@ int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename
recognized = 1; recognized = 1;
} }
syntax = 1; syntax = 1;
syntax = syntax && parse_token("basic_cpuid", token, value, data->basic_cpuid, 32, &recognized); syntax = syntax && parse_token("basic_cpuid", token, value, data->basic_cpuid, MAX_CPUID_LEVEL, &recognized);
syntax = syntax && parse_token("ext_cpuid", token, value, data->ext_cpuid, 32, &recognized); syntax = syntax && parse_token("ext_cpuid", token, value, data->ext_cpuid, MAX_EXT_CPUID_LEVEL, &recognized);
syntax = syntax && parse_token("intel_fn4", token, value, data->intel_fn4, 4, &recognized); syntax = syntax && parse_token("intel_fn4", token, value, data->intel_fn4, MAX_INTELFN4_LEVEL, &recognized);
syntax = syntax && parse_token("intel_fn11", token, value, data->intel_fn11, 4, &recognized); syntax = syntax && parse_token("intel_fn11", token, value, data->intel_fn11, MAX_INTELFN11_LEVEL, &recognized);
if (!syntax) { if (!syntax) {
warnf("Error: %s:%d: Syntax error\n", filename, cur_line); warnf("Error: %s:%d: Syntax error\n", filename, cur_line);
fclose(f); fclose(f);

View file

@ -212,6 +212,9 @@ struct cpu_id_t {
/** L3 cache size in KB. Zero on most systems */ /** L3 cache size in KB. Zero on most systems */
int32_t l3_cache; int32_t l3_cache;
/** L4 cache size in KB. Zero on most systems */
int32_t l4_cache;
/** Cache associativity for the L1 data cache. -1 if undetermined */ /** Cache associativity for the L1 data cache. -1 if undetermined */
int32_t l1_assoc; int32_t l1_assoc;
@ -221,6 +224,9 @@ struct cpu_id_t {
/** Cache associativity for the L3 cache. -1 if undetermined */ /** Cache associativity for the L3 cache. -1 if undetermined */
int32_t l3_assoc; int32_t l3_assoc;
/** Cache associativity for the L4 cache. -1 if undetermined */
int32_t l4_assoc;
/** Cache-line size for L1 data cache. -1 if undetermined */ /** Cache-line size for L1 data cache. -1 if undetermined */
int32_t l1_cacheline; int32_t l1_cacheline;
@ -231,6 +237,9 @@ struct cpu_id_t {
/** Cache-line size for L3 cache. -1 if undetermined */ /** Cache-line size for L3 cache. -1 if undetermined */
int32_t l3_cacheline; int32_t l3_cacheline;
/** Cache-line size for L4 cache. -1 if undetermined */
int32_t l4_cacheline;
/** /**
* The brief and human-friendly CPU codename, which was recognized.<br> * The brief and human-friendly CPU codename, which was recognized.<br>
* Examples: * Examples:

View file

@ -372,7 +372,8 @@ enum _cache_type_t {
L1I, L1I,
L1D, L1D,
L2, L2,
L3 L3,
L4
}; };
typedef enum _cache_type_t cache_type_t; typedef enum _cache_type_t cache_type_t;
@ -397,6 +398,12 @@ static void check_case(uint8_t on, cache_type_t cache, int size, int assoc, int
data->l3_cache = size; data->l3_cache = size;
data->l3_assoc = assoc; data->l3_assoc = assoc;
data->l3_cacheline = linesize; data->l3_cacheline = linesize;
break;
case L4:
data->l4_cache = size;
data->l4_assoc = assoc;
data->l4_cacheline = linesize;
break;
default: default:
break; break;
} }
@ -517,6 +524,8 @@ static void decode_intel_deterministic_cache_info(struct cpu_raw_data_t* raw,
type = L2; type = L2;
else if (level == 3 && typenumber == 3) else if (level == 3 && typenumber == 3)
type = L3; type = L3;
else if (level == 4 && typenumber == 3)
type = L4;
else { else {
warnf("deterministic_cache: unknown level/typenumber combo (%d/%d), cannot\n", level, typenumber); warnf("deterministic_cache: unknown level/typenumber combo (%d/%d), cannot\n", level, typenumber);
warnf("deterministic_cache: recognize cache type\n"); warnf("deterministic_cache: recognize cache type\n");