1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <inttypes.h>
4
5 #include <cpuinfo.h>
6
7
report_cache(uint32_t count,const struct cpuinfo_cache * cache,uint32_t level,const char * nonunified_type)8 void report_cache(
9 uint32_t count, const struct cpuinfo_cache* cache,
10 uint32_t level, const char* nonunified_type)
11 {
12 const char* type = (cache->flags & CPUINFO_CACHE_UNIFIED) ? "unified" : nonunified_type;
13 printf("L%"PRIu32" %s cache: ", level, type);
14
15 uint32_t size = cache->size;
16 const char* units = "bytes";
17 if (size % UINT32_C(1048576) == 0) {
18 size /= UINT32_C(1048576);
19 units = "MB";
20 } else if (size % UINT32_C(1024) == 0) {
21 size /= UINT32_C(1024);
22 units = "KB";
23 }
24 if (count != 1) {
25 printf("%"PRIu32" x ", count);
26 }
27 if (level == 1) {
28 printf("%"PRIu32" %s, ", size, units);
29 } else {
30 printf("%"PRIu32" %s (%s), ", size, units, (cache->flags & CPUINFO_CACHE_INCLUSIVE) ? "inclusive" : "exclusive");
31 }
32
33 if (cache->associativity * cache->line_size == cache->size) {
34 printf("fully associative");
35 } else {
36 printf("%"PRIu32"-way set associative", cache->associativity);
37 }
38 if (cache->sets != 0) {
39 printf(" (%"PRIu32" sets", cache->sets);
40 if (cache->partitions != 1) {
41 printf(", %"PRIu32" partitions", cache->partitions);
42 }
43 if (cache->flags & CPUINFO_CACHE_COMPLEX_INDEXING) {
44 printf(", complex indexing), ");
45 } else {
46 printf("), ");
47 }
48 }
49
50 printf("%"PRIu32" byte lines", cache->line_size);
51 if (cache->processor_count != 0) {
52 printf(", shared by %"PRIu32" processors\n", cache->processor_count);
53 } else {
54 printf("\n");
55 }
56 }
57
main(int argc,char ** argv)58 int main(int argc, char** argv) {
59 if (!cpuinfo_initialize()) {
60 fprintf(stderr, "failed to initialize CPU information\n");
61 exit(EXIT_FAILURE);
62 }
63 printf("Max cache size (upper bound): %"PRIu32" bytes\n", cpuinfo_get_max_cache_size());
64
65 if (cpuinfo_get_l1i_caches_count() != 0 && (cpuinfo_get_l1i_cache(0)->flags & CPUINFO_CACHE_UNIFIED) == 0) {
66 report_cache(cpuinfo_get_l1i_caches_count(), cpuinfo_get_l1i_cache(0), 1, "instruction");
67 }
68 if (cpuinfo_get_l1d_caches_count() != 0) {
69 report_cache(cpuinfo_get_l1d_caches_count(), cpuinfo_get_l1d_cache(0), 1, "data");
70 }
71 if (cpuinfo_get_l2_caches_count() != 0) {
72 report_cache(cpuinfo_get_l2_caches_count(), cpuinfo_get_l2_cache(0), 2, "data");
73 }
74 if (cpuinfo_get_l3_caches_count() != 0) {
75 report_cache(cpuinfo_get_l3_caches_count(), cpuinfo_get_l3_cache(0), 3, "data");
76 }
77 if (cpuinfo_get_l4_caches_count() != 0) {
78 report_cache(cpuinfo_get_l4_caches_count(), cpuinfo_get_l4_cache(0), 4, "data");
79 }
80 }
81