PAPI 7.1.0.0
Loading...
Searching...
No Matches
x86_cpu_utils.c
Go to the documentation of this file.
1#include <string.h>
2#include <assert.h>
3#include <limits.h>
4
5#include "sysdetect.h"
6#include "x86_cpu_utils.h"
7#include "os_cpu_utils.h"
8
9typedef struct {
17
18typedef struct {
19 int pkg;
20 int core;
21 int smt;
23
24typedef struct {
25 unsigned int eax;
26 unsigned int ebx;
27 unsigned int ecx;
28 unsigned int edx;
30
32
33static int cpuid_get_vendor( char *vendor );
34static int cpuid_get_name( char *name );
35static int cpuid_get_attribute( CPU_attr_e attr, int *value );
36static int cpuid_get_attribute_at( CPU_attr_e attr, int loc, int *value );
37static int cpuid_get_topology_info( CPU_attr_e attr, int *value );
38static int cpuid_get_cache_info( CPU_attr_e attr, int level, int *value );
39static int intel_get_cache_info( CPU_attr_e attr, int level, int *value );
40static int amd_get_cache_info( CPU_attr_e attr, int level, int *value );
41static int cpuid_supports_leaves_4_11( void );
42static int enum_cpu_resources( int num_mappings, apic_subid_mask_t *mask,
43 apic_subid_t *subids, int *sockets,
44 int *cores, int *threads );
45static int cpuid_get_versioning_info( CPU_attr_e attr, int *value );
46static int cpuid_parse_id_foreach_thread( unsigned int num_mappings,
48 apic_subid_t *subid );
49static int cpuid_parse_ids( int os_proc_count,
51 apic_subid_t *subid );
52static int cpuid_get_mask( apic_subid_mask_t *mask );
54static int cpuid_get_leaf4_mask( apic_subid_mask_t *mask );
55static unsigned int cpuid_get_x2apic_id( void );
56static unsigned int cpuid_get_apic_id( void );
57static unsigned int bit_width( unsigned int x );
58static void cpuid( cpuid_reg_t *reg, const unsigned int func );
59static void cpuid2( cpuid_reg_t *reg, const unsigned int func, const unsigned int subfunc );
60
61static int cpuid_has_leaf4; /* support legacy leaf1 and leaf4 interface */
62static int cpuid_has_leaf11; /* support modern leaf11 interface */
63
64int
66{
67 /*
68 * In the future we might need to dynamically
69 * allocate and free objects; init/finalize
70 * functions are a good place for doing that.
71 */
72 return CPU_SUCCESS;
73}
74
75int
77{
78 return CPU_SUCCESS;
79}
80
81int
82x86_cpu_get_vendor( char *vendor )
83{
84 return cpuid_get_vendor(vendor);
85}
86
87int
89{
90 return cpuid_get_name(name);
91}
92
93int
95{
96 return cpuid_get_attribute(attr, value);
97}
98
99int
100x86_cpu_get_attribute_at( CPU_attr_e attr, int loc, int *value )
101{
102 return cpuid_get_attribute_at(attr, loc, value);
103}
104
105int
106cpuid_get_vendor( char *vendor )
107{
108 cpuid_reg_t reg;
109 cpuid(&reg, 0); /* Highest function parameter and manufacturer ID */
110 memcpy(vendor , &reg.ebx, 4);
111 memcpy(vendor + 4, &reg.edx, 4);
112 memcpy(vendor + 8, &reg.ecx, 4);
113 vendor[12] = '\0';
114 return CPU_SUCCESS;
115}
116
117int
119{
120 cpuid_reg_t reg;
121 cpuid(&reg, 0x80000000);
122 if (reg.eax < 0x80000004) {
123 /* Feature not implemented. Fallback! */
124 return os_cpu_get_name(name);
125 }
126
127 cpuid(&reg, 0x80000002);
128 memcpy(name , &reg.eax, 4);
129 memcpy(name + 4 , &reg.ebx, 4);
130 memcpy(name + 8 , &reg.ecx, 4);
131 memcpy(name + 12, &reg.edx, 4);
132
133 cpuid(&reg, 0x80000003);
134 memcpy(name + 16, &reg.eax, 4);
135 memcpy(name + 20, &reg.ebx, 4);
136 memcpy(name + 24, &reg.ecx, 4);
137 memcpy(name + 28, &reg.edx, 4);
138
139 cpuid(&reg, 0x80000004);
140 memcpy(name + 32, &reg.eax, 4);
141 memcpy(name + 36, &reg.ebx, 4);
142 memcpy(name + 40, &reg.ecx, 4);
143 memcpy(name + 44, &reg.edx, 4);
144
145 name[48] = '\0';
146
147 return CPU_SUCCESS;
148}
149
150int
152{
153 int status = CPU_SUCCESS;
154
155 switch(attr) {
160 status = cpuid_get_topology_info(attr, value);
161 break;
165 status = cpuid_get_versioning_info(attr, value);
166 break;
169 break;
170 default:
171 status = os_cpu_get_attribute(attr, value);
172 }
173
174 return status;
175}
176
177int
178cpuid_get_attribute_at( CPU_attr_e attr, int loc, int *value )
179{
180 int status = CPU_SUCCESS;
181
182 switch(attr) {
198 status = cpuid_get_cache_info(attr, loc, value);
199 break;
202 status = os_cpu_get_attribute_at(attr, loc, value);
203 break;
204 default:
205 status = CPU_ERROR;
206 }
207
208 return status;
209}
210
211int
213{
214 int status = CPU_SUCCESS;
215 static int sockets, nodes, cores, threads;
216
217 if (attr == CPU_ATTR__NUM_SOCKETS && sockets) {
218 *value = sockets;
219 return status;
220 } else if (attr == CPU_ATTR__NUM_THREADS && threads) {
221 *value = threads;
222 return status;
223 } else if (attr == CPU_ATTR__NUM_CORES && cores) {
224 *value = cores;
225 return status;
226 } else if (attr == CPU_ATTR__NUM_NODES && nodes) {
227 *value = nodes;
228 return status;
229 }
230
231 /* Query for cpuid supported topology enumeration capabilities:
232 * - cpuid in the first generation of Intel Xeon and Intel Pentium 4
233 * supporting hyper-threading (2002) provides information that allows
234 * to decompose the 8-bit wide APIC IDs into a two-level topology
235 * enumeration;
236 * - with the introduction of dual-core Intel 64 processors in 2005,
237 * system topology enumeration using cpuid evolved into a three-level
238 * algorithm (to account for physical cores) on the 8-bit wide APIC ID;
239 * - modern Intel 64 platforms with support for large number of logical
240 * processors use an extended 32-bit wide x2APIC ID. This is known as
241 * cpuid leaf11 interface. Legacy cpuid interface with limited 256
242 * APIC IDs, is referred to as leaf4. */
244 return os_cpu_get_attribute(attr, value);
245 }
246
247 /* Allocate SUBIDs' space for each logical processor */
248 int os_proc_count = os_cpu_get_num_supported();
249 apic_subid_t *subids = papi_malloc(os_proc_count * sizeof(*subids));
250 if (!subids)
251 return CPU_ERROR;
252
253 /* Get masks for later SUBIDs extraction */
254 apic_subid_mask_t mask = { 0 };
255 if (cpuid_get_mask(&mask))
256 goto fn_fail;
257
258 /* For each logical processor get the unique APIC/x2APIC ID and use
259 * use previously retrieved masks to extract package, core and smt
260 * SUBIDs. */
261 int num_mappings = cpuid_parse_ids(os_proc_count, &mask, subids);
262 if (num_mappings == -1)
263 goto fn_fail;
264
265 /* Enumerate all cpu resources once and store them for later */
266 status = enum_cpu_resources(num_mappings, &mask, subids, &sockets,
267 &cores, &threads);
268 if (status != CPU_SUCCESS)
269 goto fn_fail;
270
271 if (attr == CPU_ATTR__NUM_SOCKETS && sockets) {
272 *value = sockets;
273 } else if (attr == CPU_ATTR__NUM_THREADS && threads) {
274 *value = threads;
275 } else if (attr == CPU_ATTR__NUM_CORES && cores) {
276 *value = cores;
277 } else if (attr == CPU_ATTR__NUM_NODES) {
278 /* We can't read the number of numa nodes using cpuid */
279 status = os_cpu_get_attribute(attr, &nodes);
280 *value = nodes;
281 }
282
283 /* Parse subids and get package, core and smt counts */
284 papi_free(subids);
285
286 fn_exit:
287 return status;
288 fn_fail:
289 papi_free(subids);
290 status = CPU_ERROR;
291 goto fn_exit;
292}
293
294int
295cpuid_get_cache_info( CPU_attr_e attr, int level, int *value )
296{
297 int status = CPU_SUCCESS;
298 char vendor[13] = { 0 };
299
300 cpuid_get_vendor(vendor);
301
302 if (!strcmp(vendor, "GenuineIntel")) {
303 status = intel_get_cache_info(attr, level, value);
304 } else if (!strcmp(vendor, "AuthenticAMD")) {
305 status = amd_get_cache_info(attr, level, value);
306 } else {
307 status = CPU_ERROR;
308 }
309
310 return status;
311}
312
313int
314intel_get_cache_info( CPU_attr_e attr, int level, int *value )
315{
316 static _sysdetect_cache_level_info_t *clevel_ptr;
317
318 if (clevel_ptr) {
319 return cpu_get_cache_info(attr, level, clevel_ptr, value);
320 }
321
323 return os_cpu_get_attribute_at(attr, level, value);
324 }
325
326 clevel_ptr = clevel;
327
328 cpuid_reg_t reg;
329 int subleaf = 0;
330 while(1) {
331 /*
332 * We query cache info only for the logical processor we are running on
333 * and rely on the fact that the rest are all identical
334 */
335 cpuid2(&reg, 4, subleaf);
336
337 /*
338 * Decoded as per table 3-12 in Intel's Software Developer's Manual
339 * Volume 2A
340 */
341 int type = reg.eax & 0x1f;
342 if (type == 0)
343 break;
344
345 switch(type) {
346 case 1:
348 break;
349 case 2:
351 break;
352 case 3:
354 break;
355 default:
357 }
358
359 int level = (reg.eax >> 5) & 0x3;
360 int fully_assoc = (reg.eax >> 9) & 0x1;
361 int line_size = (reg.ebx & 0xfff) + 1;
362 int partitions = ((reg.ebx >> 12) & 0x3ff) + 1;
363 int ways = ((reg.ebx >> 22) & 0x3ff) + 1;
364 int sets = (reg.ecx + 1);
365
366 int *num_caches = &clevel[level-1].num_caches;
367 clevel_ptr[level-1].cache[*num_caches].type = type;
368 clevel_ptr[level-1].cache[*num_caches].size = (ways * partitions * sets * line_size);
369 clevel_ptr[level-1].cache[*num_caches].line_size = line_size;
370 clevel_ptr[level-1].cache[*num_caches].num_lines = (ways * partitions * sets);
371 clevel_ptr[level-1].cache[*num_caches].associativity = (fully_assoc) ? SHRT_MAX : ways;
372 ++(*num_caches);
373
374 ++subleaf;
375 }
376
377 return cpu_get_cache_info(attr, level, clevel_ptr, value);
378}
379
380int
381amd_get_cache_info( CPU_attr_e attr, int level, int *value )
382{
383 static _sysdetect_cache_level_info_t *clevel_ptr;
384
385 if (clevel_ptr) {
386 return cpu_get_cache_info(attr, level, clevel_ptr, value);
387 }
388
389 cpuid_reg_t reg;
390
391 /* L1 Caches */
392 cpuid(&reg, 0x80000005);
393
394 unsigned char byt[16];
395 memcpy(byt , &reg.eax, 4);
396 memcpy(byt + 4 , &reg.ebx, 4);
397 memcpy(byt + 8 , &reg.ecx, 4);
398 memcpy(byt + 12, &reg.edx, 4);
399
400 clevel_ptr = clevel;
401 clevel_ptr[0].cache[0].type = PAPI_MH_TYPE_DATA;
402 clevel_ptr[0].cache[0].size = byt[11] << 10;
403 clevel_ptr[0].cache[0].line_size = byt[8];
404 clevel_ptr[0].cache[0].num_lines = clevel_ptr[0].cache[0].size / clevel_ptr[0].cache[0].line_size;
405 clevel_ptr[0].cache[0].associativity = byt[10];
406
407 clevel_ptr[0].cache[1].type = PAPI_MH_TYPE_INST;
408 clevel_ptr[0].cache[1].size = byt[15] << 10;
409 clevel_ptr[0].cache[1].line_size = byt[12];
410 clevel_ptr[0].cache[1].num_lines = clevel_ptr[0].cache[1].size / clevel_ptr[0].cache[1].line_size;
411 clevel_ptr[0].cache[1].associativity = byt[14];
412
413 clevel_ptr[0].num_caches = 2;
414
415 /* L2 and L3 caches */
416 cpuid(&reg, 0x80000006);
417
418 memcpy(byt , &reg.eax, 4);
419 memcpy(byt + 4 , &reg.ebx, 4);
420 memcpy(byt + 8 , &reg.ecx, 4);
421 memcpy(byt + 12, &reg.edx, 4);
422
423 static short int assoc[16] = {
424 0, 1, 2, -1, 4, -1, 8, -1, 16, -1, 32, 48, 64, 96, 128, SHRT_MAX
425 };
426
427 if (reg.ecx) {
428 clevel_ptr[1].cache[0].type = PAPI_MH_TYPE_UNIFIED;
429 clevel_ptr[1].cache[0].size = (int)((reg.ecx & 0xffff0000) >> 6);
430 clevel_ptr[1].cache[0].line_size = byt[8];
431 clevel_ptr[1].cache[0].num_lines = clevel_ptr[1].cache[0].size / clevel_ptr[1].cache[0].line_size;
432 clevel_ptr[1].cache[0].associativity = assoc[(byt[9] & 0xf0) >> 4];
433 clevel_ptr[1].num_caches = 1;
434 }
435
436 if (reg.edx) {
437 clevel_ptr[2].cache[0].type = PAPI_MH_TYPE_UNIFIED;
438 clevel_ptr[2].cache[0].size = (int)((reg.edx & 0xfffc0000) << 1);
439 clevel_ptr[2].cache[0].line_size = byt[12];
440 clevel_ptr[2].cache[0].num_lines = clevel_ptr[1].cache[0].size / clevel_ptr[1].cache[0].line_size;
441 clevel_ptr[2].cache[0].associativity = assoc[(byt[13] & 0xf0) >> 4];
442 clevel_ptr[2].num_caches = 1;
443 }
444
445 return cpu_get_cache_info(attr, level, clevel_ptr, value);
446}
447
448int
450{
451 char vendor[13];
452 cpuid_get_vendor(vendor);
453
454 cpuid_reg_t reg;
455 cpuid(&reg, 0);
456
457 /* If leaf4 not supported or vendor is not Intel, fallback */
458 int fallback = (reg.eax < 4 || strcmp(vendor, "GenuineIntel"));
459 if (!fallback) {
460 cpuid_has_leaf4 = 1;
461 cpuid(&reg, 11);
462 if (reg.ebx != 0)
464 }
465
466 return !fallback;
467}
468
469int
470enum_cpu_resources( int num_mappings, apic_subid_mask_t *mask,
471 apic_subid_t *subids, int *sockets,
472 int *cores, int *threads )
473{
474 int status = CPU_SUCCESS;
475 int max_num_pkgs = (1 << mask->pkg_width);
476 int max_num_cores = (1 << mask->core_width);
477 int max_num_threads = (1 << mask->smt_width);
478
479 int *pkg_arr = papi_calloc(max_num_pkgs, sizeof(int));
480 if (!pkg_arr)
481 goto fn_fail_pkg;
482
483 int *core_arr = papi_calloc(max_num_cores, sizeof(int));
484 if (!core_arr)
485 goto fn_fail_core;
486
487 int *smt_arr = papi_calloc(max_num_threads, sizeof(int));
488 if (!smt_arr)
489 goto fn_fail_thread;
490
491 int i;
492 for (i = 0; i < num_mappings; ++i) {
493 pkg_arr[subids[i].pkg] =
494 core_arr[subids[i].core] =
495 smt_arr[subids[i].smt] = 1;
496 }
497
498 i = 0, *sockets = 0;
499 while (i < max_num_pkgs) {
500 if (pkg_arr[i++] != 0)
501 (*sockets)++;
502 }
503
504 i = 0, *cores = 0;
505 while (i < max_num_cores) {
506 if (core_arr[i++] != 0)
507 (*cores)++;
508 }
509
510 i = 0, *threads = 0;
511 while (i < max_num_threads) {
512 if (smt_arr[i++] != 0)
513 (*threads)++;
514 }
515
516 papi_free(pkg_arr);
517 papi_free(core_arr);
518 papi_free(smt_arr);
519
520 fn_exit:
521 return status;
522 fn_fail_thread:
523 papi_free(core_arr);
524 fn_fail_core:
525 papi_free(pkg_arr);
526 fn_fail_pkg:
527 status = CPU_ERROR;
528 goto fn_exit;
529}
530
531int
533{
534 static int family, model, stepping;
535
536 if (attr == CPU_ATTR__CPUID_FAMILY && family) {
537 *value = family;
538 return CPU_SUCCESS;
539 } else if (attr == CPU_ATTR__CPUID_MODEL && model) {
540 *value = model;
541 return CPU_SUCCESS;
542 } else if (attr == CPU_ATTR__CPUID_STEPPING && stepping) {
543 *value = stepping;
544 return CPU_SUCCESS;
545 }
546
547 cpuid_reg_t reg;
548 cpuid(&reg, 1);
549
550 /* Query versioning info once and store results for later */
551 family = (reg.eax >> 8) & 0x0000000f;
552 model = (family == 6 || family == 15) ?
553 ((reg.eax >> 4) & 0x0000000f) + ((reg.eax >> 12) & 0x000000f0) :
554 ((reg.eax >> 4) & 0x0000000f);
555 stepping = reg.eax & 0x0000000f;
556
557 char vendor[13];
558 cpuid_get_vendor(vendor);
559 if (!strcmp(vendor, "AuthenticAMD") && family == 15) {
560 /* Adjust family for AMD processors */
561 family += (reg.eax >> 20) & 0x000000ff;
562 }
563
564 if (attr == CPU_ATTR__CPUID_FAMILY) {
565 *value = family;
566 } else if (attr == CPU_ATTR__CPUID_MODEL) {
567 *value = model;
568 } else {
569 *value = stepping;
570 }
571
572 return CPU_SUCCESS;
573}
574
575int
576cpuid_parse_id_foreach_thread( unsigned int num_mappings,
577 apic_subid_mask_t *mask,
578 apic_subid_t *subid )
579{
580 unsigned int apic_id = cpuid_get_apic_id();
581 subid[num_mappings].pkg = ((apic_id & mask->pkg_mask ) >> (mask->smt_width + mask->core_width));
582 subid[num_mappings].core = ((apic_id & mask->core_mask) >> (mask->smt_width));
583 subid[num_mappings].smt = ((apic_id & mask->smt_mask ));
584 return CPU_SUCCESS;
585}
586
587int
588cpuid_parse_ids( int os_proc_count, apic_subid_mask_t *mask, apic_subid_t *subid )
589{
590 int i, ret = 0;
591 int num_mappings = 0;
592
593 /* save cpu affinity */
595
596 for (i = 0; i < os_proc_count; ++i) {
597 /* check if we are allowed to run on this logical processor */
598 if (os_cpu_set_affinity(i)) {
599 ret = -1;
600 break;
601 }
602
603 /* now query id for the logical processor */
604 cpuid_parse_id_foreach_thread(num_mappings, mask, subid);
605
606 /* increment parsed ids */
607 ret = ++num_mappings;
608 }
609
610 /* restore cpu affinity */
612
613 return ret;
614}
615
616int
618{
619 if (cpuid_has_leaf11) {
620 return cpuid_get_leaf11_mask(mask);
621 }
622
623 return cpuid_get_leaf4_mask(mask);
624}
625
626int
628{
629 int status = CPU_SUCCESS;
630 int core_reported = 0;
631 int thread_reported = 0;
632 int sub_leaf = 0, level_type, level_shift;
633 unsigned int core_plus_smt_mask = 0;
634 unsigned int core_plus_smt_width = 0;
635
636 do {
637 cpuid_reg_t reg;
638 cpuid2(&reg, 11, sub_leaf);
639 if (reg.ebx == 0)
640 break;
641
642 level_type = (reg.ecx >> 8) & 0x000000ff;
643 level_shift = reg.eax & 0x0000001f;
644
645 /*
646 * x2APIC ID layout (32 bits)
647 * +---------+----------+---------+
648 * | pkg | core | smt |
649 * +---------+----------+---------+
650 * <--------->
651 * level type = 1
652 * level shift = smt width
653 * <-------------------->
654 * level type = 2
655 * level shift = core + smt width
656 *
657 */
658 switch (level_type) {
659 case 1: /* level type is SMT, so the mask width is level shift */
660 mask->smt_mask = ~(0xFFFFFFFF << level_shift);
661 mask->smt_width = level_shift;
662 thread_reported = 1;
663 break;
664 case 2: /* level type is core, so the core + smt mask width is level shift */
665 core_plus_smt_mask = ~(0xFFFFFFFF << level_shift);
666 core_plus_smt_width = level_shift;
667 mask->pkg_mask = 0xFFFFFFFF ^ core_plus_smt_mask;
668 mask->pkg_width = 8; /* use reasonably high value */
669 core_reported = 1;
670 break;
671 default:
672 break;
673 }
674 ++sub_leaf;
675 } while(1);
676
677 if (thread_reported && core_reported) {
678 mask->core_mask = core_plus_smt_mask ^ mask->smt_mask;
679 mask->core_width = core_plus_smt_width - mask->smt_width;
680 } else if (!core_reported && thread_reported) {
681 mask->core_mask = 0;
682 mask->core_width = 0;
683 mask->pkg_mask = 0xFFFFFFFF ^ mask->smt_mask;
684 mask->pkg_width = 8; /* use reasonably high value */
685 } else {
686 status = CPU_ERROR;
687 }
688
689 return status;
690}
691
692int
694{
695 cpuid_reg_t reg;
696 cpuid(&reg, 1);
697 unsigned int core_plus_smt_max_cnt = (reg.ebx >> 16) & 0x000000ff;
698
699 cpuid(&reg, 4);
700 unsigned int core_max_cnt = ((reg.eax >> 26) & 0x0000003f) + 1;
701
702 unsigned int core_width = bit_width(core_max_cnt);
703 unsigned int smt_width = bit_width(core_plus_smt_max_cnt) - core_width;
704
705 mask->smt_mask = ~(0xFFFFFFFF << smt_width);
706 mask->smt_width = smt_width;
707 mask->core_mask = ~(0xFFFFFFFF << bit_width(core_plus_smt_max_cnt)) ^ mask->smt_mask;
708 mask->core_width = core_width;
709 mask->pkg_mask = 0xFFFFFFFF << bit_width(core_plus_smt_max_cnt);
710 mask->pkg_width = 8; /* use reasonably high value */
711
712 return CPU_SUCCESS;
713}
714
715unsigned int
717{
718 cpuid_reg_t reg;
719 cpuid(&reg, 11);
720 return reg.edx;
721}
722
723unsigned int
725{
726 if (cpuid_has_leaf11) {
727 return cpuid_get_x2apic_id();
728 }
729
730 cpuid_reg_t reg;
731 cpuid(&reg, 1);
732 return (reg.ebx >> 24) & 0x000000ff;
733}
734
735unsigned int
736bit_width( unsigned int x )
737{
738 int count = 0;
739 double y = (double) x;
740
741 while ((y /= 2) > 1) {
742 ++count;
743 }
744
745 return (y < 1) ? count + 1 : count;
746}
747
748void
749cpuid2( cpuid_reg_t *reg, unsigned int func, unsigned int subfunc )
750{
751 __asm__ ("cpuid;"
752 : "=a" (reg->eax), "=b" (reg->ebx), "=c" (reg->ecx), "=d" (reg->edx)
753 : "a" (func), "c" (subfunc));
754}
755
756void
757cpuid( cpuid_reg_t *reg, unsigned int func )
758{
759 cpuid2(reg, func, 0);
760}
int i
static long count
int cpu_get_cache_info(CPU_attr_e attr, int level, _sysdetect_cache_level_info_t *clevel_ptr, int *value)
Definition: cpu_utils.c:94
#define CPU_ERROR
Definition: cpu_utils.h:5
#define CPU_SUCCESS
Definition: cpu_utils.h:4
CPU_attr_e
Definition: cpu_utils.h:7
@ CPU_ATTR__CPUID_MODEL
Definition: cpu_utils.h:14
@ CPU_ATTR__CACHE_MAX_NUM_LEVELS
Definition: cpu_utils.h:17
@ CPU_ATTR__NUM_THREADS
Definition: cpu_utils.h:11
@ CPU_ATTR__CPUID_FAMILY
Definition: cpu_utils.h:13
@ CPU_ATTR__CACHE_INST_TOT_SIZE
Definition: cpu_utils.h:21
@ CPU_ATTR__HWTHREAD_NUMA_AFFINITY
Definition: cpu_utils.h:34
@ CPU_ATTR__CACHE_UNIF_TOT_SIZE
Definition: cpu_utils.h:29
@ CPU_ATTR__CACHE_DATA_ASSOCIATIVITY
Definition: cpu_utils.h:28
@ CPU_ATTR__CACHE_INST_LINE_SIZE
Definition: cpu_utils.h:22
@ CPU_ATTR__NUMA_MEM_SIZE
Definition: cpu_utils.h:36
@ CPU_ATTR__NUM_NODES
Definition: cpu_utils.h:9
@ CPU_ATTR__CACHE_UNIF_LINE_SIZE
Definition: cpu_utils.h:30
@ CPU_ATTR__CACHE_DATA_NUM_LINES
Definition: cpu_utils.h:27
@ CPU_ATTR__CACHE_UNIF_ASSOCIATIVITY
Definition: cpu_utils.h:32
@ CPU_ATTR__CPUID_STEPPING
Definition: cpu_utils.h:15
@ CPU_ATTR__CACHE_INST_PRESENT
Definition: cpu_utils.h:18
@ CPU_ATTR__NUM_CORES
Definition: cpu_utils.h:10
@ CPU_ATTR__CACHE_DATA_PRESENT
Definition: cpu_utils.h:19
@ CPU_ATTR__CACHE_DATA_LINE_SIZE
Definition: cpu_utils.h:26
@ CPU_ATTR__CACHE_INST_ASSOCIATIVITY
Definition: cpu_utils.h:24
@ CPU_ATTR__CACHE_INST_NUM_LINES
Definition: cpu_utils.h:23
@ CPU_ATTR__CACHE_UNIF_NUM_LINES
Definition: cpu_utils.h:31
@ CPU_ATTR__CACHE_DATA_TOT_SIZE
Definition: cpu_utils.h:25
@ CPU_ATTR__NUM_SOCKETS
Definition: cpu_utils.h:8
@ CPU_ATTR__CACHE_UNIF_PRESENT
Definition: cpu_utils.h:20
#define PAPI_MAX_MEM_HIERARCHY_LEVELS
Definition: f90papi.h:103
uint16_t type
int os_cpu_get_attribute(CPU_attr_e attr, int *value)
Definition: os_cpu_utils.c:30
int os_cpu_get_num_supported(void)
Definition: os_cpu_utils.c:66
int os_cpu_set_affinity(int cpu)
Definition: os_cpu_utils.c:54
int os_cpu_load_affinity(void)
Definition: os_cpu_utils.c:90
int os_cpu_get_attribute_at(CPU_attr_e attr, int loc, int *value)
Definition: os_cpu_utils.c:42
int os_cpu_get_name(char *name)
Definition: os_cpu_utils.c:18
int os_cpu_store_affinity(void)
Definition: os_cpu_utils.c:78
#define PAPI_MH_TYPE_DATA
Definition: papi.h:720
#define PAPI_MH_TYPE_INST
Definition: papi.h:719
#define PAPI_MH_TYPE_UNKNOWN
Definition: papi.h:728
#define PAPI_MH_TYPE_UNIFIED
Definition: papi.h:723
#define papi_calloc(a, b)
Definition: papi_memory.h:37
#define papi_free(a)
Definition: papi_memory.h:35
#define papi_malloc(a)
Definition: papi_memory.h:34
int model
Definition: pfmlib_amd64.c:86
int family
Definition: pfmlib_amd64.c:85
int stepping
Definition: pfmlib_amd64.c:87
const char * name
Definition: rocs.c:225
int
Definition: sde_internal.h:89
PAPI_mh_cache_info_t cache[PAPI_MH_MAX_LEVELS]
Definition: sysdetect.h:57
unsigned int ecx
Definition: x86_cpu_utils.c:27
unsigned int edx
Definition: x86_cpu_utils.c:28
unsigned int ebx
Definition: x86_cpu_utils.c:26
unsigned int eax
Definition: x86_cpu_utils.c:25
volatile double y
volatile double x
static int cpuid_parse_ids(int os_proc_count, apic_subid_mask_t *mask, apic_subid_t *subid)
static int cpuid_get_attribute(CPU_attr_e attr, int *value)
int x86_cpu_get_attribute_at(CPU_attr_e attr, int loc, int *value)
static void cpuid(cpuid_reg_t *reg, const unsigned int func)
static int cpuid_get_topology_info(CPU_attr_e attr, int *value)
static int cpuid_supports_leaves_4_11(void)
static void cpuid2(cpuid_reg_t *reg, const unsigned int func, const unsigned int subfunc)
static int cpuid_get_cache_info(CPU_attr_e attr, int level, int *value)
static int enum_cpu_resources(int num_mappings, apic_subid_mask_t *mask, apic_subid_t *subids, int *sockets, int *cores, int *threads)
static int cpuid_has_leaf4
Definition: x86_cpu_utils.c:61
int x86_cpu_get_vendor(char *vendor)
Definition: x86_cpu_utils.c:82
static int cpuid_get_leaf4_mask(apic_subid_mask_t *mask)
static unsigned int cpuid_get_x2apic_id(void)
static _sysdetect_cache_level_info_t clevel[PAPI_MAX_MEM_HIERARCHY_LEVELS]
Definition: x86_cpu_utils.c:31
static int cpuid_parse_id_foreach_thread(unsigned int num_mappings, apic_subid_mask_t *mask, apic_subid_t *subid)
static unsigned int cpuid_get_apic_id(void)
static int cpuid_get_leaf11_mask(apic_subid_mask_t *mask)
static int cpuid_get_mask(apic_subid_mask_t *mask)
int x86_cpu_finalize(void)
Definition: x86_cpu_utils.c:76
static int intel_get_cache_info(CPU_attr_e attr, int level, int *value)
static unsigned int bit_width(unsigned int x)
static int amd_get_cache_info(CPU_attr_e attr, int level, int *value)
static int cpuid_get_vendor(char *vendor)
int x86_cpu_get_attribute(CPU_attr_e attr, int *value)
Definition: x86_cpu_utils.c:94
int x86_cpu_get_name(char *name)
Definition: x86_cpu_utils.c:88
int x86_cpu_init(void)
Definition: x86_cpu_utils.c:65
static int cpuid_get_name(char *name)
static int cpuid_has_leaf11
Definition: x86_cpu_utils.c:62
static int cpuid_get_attribute_at(CPU_attr_e attr, int loc, int *value)
static int cpuid_get_versioning_info(CPU_attr_e attr, int *value)