turbostat.c (2f32edf12c1eafc8e5b1b0337360993fde1b3565) turbostat.c (8e180f3cb6b7510a3bdf14e16ce87c9f5d86f102)
1/*
2 * turbostat -- show CPU frequency and C-state residency
3 * on modern Intel turbo-capable processors.
4 *
5 * Copyright (c) 2012 Intel Corporation.
6 * Len Brown <len.brown@intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it

--- 51 unchanged lines hidden (view full) ---

60unsigned int units = 1000000000; /* Ghz etc */
61unsigned int genuine_intel;
62unsigned int has_invariant_tsc;
63unsigned int do_nehalem_platform_info;
64unsigned int do_nehalem_turbo_ratio_limit;
65unsigned int do_ivt_turbo_ratio_limit;
66unsigned int extra_msr_offset32;
67unsigned int extra_msr_offset64;
1/*
2 * turbostat -- show CPU frequency and C-state residency
3 * on modern Intel turbo-capable processors.
4 *
5 * Copyright (c) 2012 Intel Corporation.
6 * Len Brown <len.brown@intel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it

--- 51 unchanged lines hidden (view full) ---

60unsigned int units = 1000000000; /* Ghz etc */
61unsigned int genuine_intel;
62unsigned int has_invariant_tsc;
63unsigned int do_nehalem_platform_info;
64unsigned int do_nehalem_turbo_ratio_limit;
65unsigned int do_ivt_turbo_ratio_limit;
66unsigned int extra_msr_offset32;
67unsigned int extra_msr_offset64;
68unsigned int extra_delta_offset32;
69unsigned int extra_delta_offset64;
68double bclk;
69unsigned int show_pkg;
70unsigned int show_core;
71unsigned int show_cpu;
72unsigned int show_pkg_only;
73unsigned int show_core_only;
74char *output_buffer, *outp;
75

--- 5 unchanged lines hidden (view full) ---

81size_t cpu_present_setsize, cpu_affinity_setsize;
82
83struct thread_data {
84 unsigned long long tsc;
85 unsigned long long aperf;
86 unsigned long long mperf;
87 unsigned long long c1; /* derived */
88 unsigned long long extra_msr64;
70double bclk;
71unsigned int show_pkg;
72unsigned int show_core;
73unsigned int show_cpu;
74unsigned int show_pkg_only;
75unsigned int show_core_only;
76char *output_buffer, *outp;
77

--- 5 unchanged lines hidden (view full) ---

83size_t cpu_present_setsize, cpu_affinity_setsize;
84
85struct thread_data {
86 unsigned long long tsc;
87 unsigned long long aperf;
88 unsigned long long mperf;
89 unsigned long long c1; /* derived */
90 unsigned long long extra_msr64;
89 unsigned int extra_msr32;
91 unsigned long long extra_delta64;
92 unsigned long long extra_msr32;
93 unsigned long long extra_delta32;
90 unsigned int cpu_id;
91 unsigned int flags;
92#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
93#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4
94} *thread_even, *thread_odd;
95
96struct core_data {
97 unsigned long long c3;

--- 105 unchanged lines hidden (view full) ---

203 close(fd);
204
205 if (retval != sizeof *msr)
206 return -1;
207
208 return 0;
209}
210
94 unsigned int cpu_id;
95 unsigned int flags;
96#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
97#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4
98} *thread_even, *thread_odd;
99
100struct core_data {
101 unsigned long long c3;

--- 105 unchanged lines hidden (view full) ---

207 close(fd);
208
209 if (retval != sizeof *msr)
210 return -1;
211
212 return 0;
213}
214
211/*
212 * Truncate the 8 bytes we read from /dev/cpu/.../msr
213 * to the 4 bytes requested
214 */
215
216int get_msr32(int cpu, off_t offset, unsigned int *msr)
217{
218 int retval;
219
220 unsigned long long msr64;
221
222 retval = get_msr(cpu, offset, &msr64);
223 *msr = (unsigned int) msr64;
224
225 return retval;
226}
227
228
229void print_header(void)
230{
231 if (show_pkg)
232 outp += sprintf(outp, "pk");
233 if (show_pkg)
234 outp += sprintf(outp, " ");
235 if (show_core)
236 outp += sprintf(outp, "cor");
237 if (show_cpu)
238 outp += sprintf(outp, " CPU");
239 if (show_pkg || show_core || show_cpu)
240 outp += sprintf(outp, " ");
241 if (do_nhm_cstates)
242 outp += sprintf(outp, " %%c0");
243 if (has_aperf)
244 outp += sprintf(outp, " GHz");
245 outp += sprintf(outp, " TSC");
215void print_header(void)
216{
217 if (show_pkg)
218 outp += sprintf(outp, "pk");
219 if (show_pkg)
220 outp += sprintf(outp, " ");
221 if (show_core)
222 outp += sprintf(outp, "cor");
223 if (show_cpu)
224 outp += sprintf(outp, " CPU");
225 if (show_pkg || show_core || show_cpu)
226 outp += sprintf(outp, " ");
227 if (do_nhm_cstates)
228 outp += sprintf(outp, " %%c0");
229 if (has_aperf)
230 outp += sprintf(outp, " GHz");
231 outp += sprintf(outp, " TSC");
232 if (extra_delta_offset32)
233 outp += sprintf(outp, " delta 0x%03X", extra_delta_offset32);
234 if (extra_delta_offset64)
235 outp += sprintf(outp, " DELTA 0x%03X", extra_delta_offset64);
246 if (extra_msr_offset32)
236 if (extra_msr_offset32)
247 outp += sprintf(outp, " MSR 0x%04X", extra_msr_offset32);
237 outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32);
248 if (extra_msr_offset64)
238 if (extra_msr_offset64)
249 outp += sprintf(outp, " MSR 0x%04X", extra_msr_offset64);
239 outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64);
250 if (do_nhm_cstates)
251 outp += sprintf(outp, " %%c1");
252 if (do_nhm_cstates)
253 outp += sprintf(outp, " %%c3");
254 if (do_nhm_cstates)
255 outp += sprintf(outp, " %%c6");
256 if (do_snb_cstates)
257 outp += sprintf(outp, " %%c7");

--- 15 unchanged lines hidden (view full) ---

273 fprintf(stderr, "t %p, c %p, p %p\n", t, c, p);
274
275 if (t) {
276 fprintf(stderr, "CPU: %d flags 0x%x\n", t->cpu_id, t->flags);
277 fprintf(stderr, "TSC: %016llX\n", t->tsc);
278 fprintf(stderr, "aperf: %016llX\n", t->aperf);
279 fprintf(stderr, "mperf: %016llX\n", t->mperf);
280 fprintf(stderr, "c1: %016llX\n", t->c1);
240 if (do_nhm_cstates)
241 outp += sprintf(outp, " %%c1");
242 if (do_nhm_cstates)
243 outp += sprintf(outp, " %%c3");
244 if (do_nhm_cstates)
245 outp += sprintf(outp, " %%c6");
246 if (do_snb_cstates)
247 outp += sprintf(outp, " %%c7");

--- 15 unchanged lines hidden (view full) ---

263 fprintf(stderr, "t %p, c %p, p %p\n", t, c, p);
264
265 if (t) {
266 fprintf(stderr, "CPU: %d flags 0x%x\n", t->cpu_id, t->flags);
267 fprintf(stderr, "TSC: %016llX\n", t->tsc);
268 fprintf(stderr, "aperf: %016llX\n", t->aperf);
269 fprintf(stderr, "mperf: %016llX\n", t->mperf);
270 fprintf(stderr, "c1: %016llX\n", t->c1);
281 fprintf(stderr, "msr0x%x: %08X\n",
271 fprintf(stderr, "msr0x%x: %08llX\n",
272 extra_delta_offset32, t->extra_delta32);
273 fprintf(stderr, "msr0x%x: %016llX\n",
274 extra_delta_offset64, t->extra_delta64);
275 fprintf(stderr, "msr0x%x: %08llX\n",
282 extra_msr_offset32, t->extra_msr32);
283 fprintf(stderr, "msr0x%x: %016llX\n",
284 extra_msr_offset64, t->extra_msr64);
285 }
286
287 if (c) {
288 fprintf(stderr, "core: %d\n", c->core_id);
289 fprintf(stderr, "c3: %016llX\n", c->c3);

--- 90 unchanged lines hidden (view full) ---

380 t->mperf / interval_float);
381 }
382 }
383 }
384
385 /* TSC */
386 outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float);
387
276 extra_msr_offset32, t->extra_msr32);
277 fprintf(stderr, "msr0x%x: %016llX\n",
278 extra_msr_offset64, t->extra_msr64);
279 }
280
281 if (c) {
282 fprintf(stderr, "core: %d\n", c->core_id);
283 fprintf(stderr, "c3: %016llX\n", c->c3);

--- 90 unchanged lines hidden (view full) ---

374 t->mperf / interval_float);
375 }
376 }
377 }
378
379 /* TSC */
380 outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float);
381
382 /* delta */
383 if (extra_delta_offset32)
384 outp += sprintf(outp, " %11llu", t->extra_delta32);
385
386 /* DELTA */
387 if (extra_delta_offset64)
388 outp += sprintf(outp, " %11llu", t->extra_delta64);
388 /* msr */
389 if (extra_msr_offset32)
389 /* msr */
390 if (extra_msr_offset32)
390 outp += sprintf(outp, " 0x%08x", t->extra_msr32);
391 outp += sprintf(outp, " 0x%08llx", t->extra_msr32);
391
392 /* MSR */
393 if (extra_msr_offset64)
394 outp += sprintf(outp, " 0x%016llx", t->extra_msr64);
395
396 if (do_nhm_cstates) {
397 if (!skip_c1)
398 outp += sprintf(outp, " %6.2f", 100.0 * t->c1/t->tsc);

--- 129 unchanged lines hidden (view full) ---

528 - core_delta->c6 - core_delta->c7;
529 }
530
531 if (old->mperf == 0) {
532 if (verbose > 1) fprintf(stderr, "cpu%d MPERF 0!\n", old->cpu_id);
533 old->mperf = 1; /* divide by 0 protection */
534 }
535
392
393 /* MSR */
394 if (extra_msr_offset64)
395 outp += sprintf(outp, " 0x%016llx", t->extra_msr64);
396
397 if (do_nhm_cstates) {
398 if (!skip_c1)
399 outp += sprintf(outp, " %6.2f", 100.0 * t->c1/t->tsc);

--- 129 unchanged lines hidden (view full) ---

529 - core_delta->c6 - core_delta->c7;
530 }
531
532 if (old->mperf == 0) {
533 if (verbose > 1) fprintf(stderr, "cpu%d MPERF 0!\n", old->cpu_id);
534 old->mperf = 1; /* divide by 0 protection */
535 }
536
537 old->extra_delta32 = new->extra_delta32 - old->extra_delta32;
538 old->extra_delta32 &= 0xFFFFFFFF;
539
540 old->extra_delta64 = new->extra_delta64 - old->extra_delta64;
541
536 /*
542 /*
537 * Extra MSR is a snapshot, simply copy latest w/o subtracting
543 * Extra MSR is just a snapshot, simply copy latest w/o subtracting
538 */
539 old->extra_msr32 = new->extra_msr32;
540 old->extra_msr64 = new->extra_msr64;
541}
542
543int delta_cpu(struct thread_data *t, struct core_data *c,
544 struct pkg_data *p, struct thread_data *t2,
545 struct core_data *c2, struct pkg_data *p2)

--- 14 unchanged lines hidden (view full) ---

560
561void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
562{
563 t->tsc = 0;
564 t->aperf = 0;
565 t->mperf = 0;
566 t->c1 = 0;
567
544 */
545 old->extra_msr32 = new->extra_msr32;
546 old->extra_msr64 = new->extra_msr64;
547}
548
549int delta_cpu(struct thread_data *t, struct core_data *c,
550 struct pkg_data *p, struct thread_data *t2,
551 struct core_data *c2, struct pkg_data *p2)

--- 14 unchanged lines hidden (view full) ---

566
567void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
568{
569 t->tsc = 0;
570 t->aperf = 0;
571 t->mperf = 0;
572 t->c1 = 0;
573
574 t->extra_delta32 = 0;
575 t->extra_delta64 = 0;
576
568 /* tells format_counters to dump all fields from this set */
569 t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
570
571 c->c3 = 0;
572 c->c6 = 0;
573 c->c7 = 0;
574
575 p->pc2 = 0;

--- 4 unchanged lines hidden (view full) ---

580int sum_counters(struct thread_data *t, struct core_data *c,
581 struct pkg_data *p)
582{
583 average.threads.tsc += t->tsc;
584 average.threads.aperf += t->aperf;
585 average.threads.mperf += t->mperf;
586 average.threads.c1 += t->c1;
587
577 /* tells format_counters to dump all fields from this set */
578 t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
579
580 c->c3 = 0;
581 c->c6 = 0;
582 c->c7 = 0;
583
584 p->pc2 = 0;

--- 4 unchanged lines hidden (view full) ---

589int sum_counters(struct thread_data *t, struct core_data *c,
590 struct pkg_data *p)
591{
592 average.threads.tsc += t->tsc;
593 average.threads.aperf += t->aperf;
594 average.threads.mperf += t->mperf;
595 average.threads.c1 += t->c1;
596
597 average.threads.extra_delta32 += t->extra_delta32;
598 average.threads.extra_delta64 += t->extra_delta64;
599
588 /* sum per-core values only for 1st thread in core */
589 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
590 return 0;
591
592 average.cores.c3 += c->c3;
593 average.cores.c6 += c->c6;
594 average.cores.c7 += c->c7;
595

--- 19 unchanged lines hidden (view full) ---

615
616 for_all_cpus(sum_counters, t, c, p);
617
618 average.threads.tsc /= topo.num_cpus;
619 average.threads.aperf /= topo.num_cpus;
620 average.threads.mperf /= topo.num_cpus;
621 average.threads.c1 /= topo.num_cpus;
622
600 /* sum per-core values only for 1st thread in core */
601 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
602 return 0;
603
604 average.cores.c3 += c->c3;
605 average.cores.c6 += c->c6;
606 average.cores.c7 += c->c7;
607

--- 19 unchanged lines hidden (view full) ---

627
628 for_all_cpus(sum_counters, t, c, p);
629
630 average.threads.tsc /= topo.num_cpus;
631 average.threads.aperf /= topo.num_cpus;
632 average.threads.mperf /= topo.num_cpus;
633 average.threads.c1 /= topo.num_cpus;
634
635 average.threads.extra_delta32 /= topo.num_cpus;
636 average.threads.extra_delta32 &= 0xFFFFFFFF;
637
638 average.threads.extra_delta64 /= topo.num_cpus;
639
623 average.cores.c3 /= topo.num_cores;
624 average.cores.c6 /= topo.num_cores;
625 average.cores.c7 /= topo.num_cores;
626
627 average.packages.pc2 /= topo.num_packages;
628 average.packages.pc3 /= topo.num_packages;
629 average.packages.pc6 /= topo.num_packages;
630 average.packages.pc7 /= topo.num_packages;

--- 25 unchanged lines hidden (view full) ---

656
657 if (has_aperf) {
658 if (get_msr(cpu, MSR_APERF, &t->aperf))
659 return -3;
660 if (get_msr(cpu, MSR_MPERF, &t->mperf))
661 return -4;
662 }
663
640 average.cores.c3 /= topo.num_cores;
641 average.cores.c6 /= topo.num_cores;
642 average.cores.c7 /= topo.num_cores;
643
644 average.packages.pc2 /= topo.num_packages;
645 average.packages.pc3 /= topo.num_packages;
646 average.packages.pc6 /= topo.num_packages;
647 average.packages.pc7 /= topo.num_packages;

--- 25 unchanged lines hidden (view full) ---

673
674 if (has_aperf) {
675 if (get_msr(cpu, MSR_APERF, &t->aperf))
676 return -3;
677 if (get_msr(cpu, MSR_MPERF, &t->mperf))
678 return -4;
679 }
680
664 if (extra_msr_offset32)
665 if (get_msr32(cpu, extra_msr_offset32, &t->extra_msr32))
681 if (extra_delta_offset32) {
682 if (get_msr(cpu, extra_delta_offset32, &t->extra_delta32))
666 return -5;
683 return -5;
684 t->extra_delta32 &= 0xFFFFFFFF;
685 }
667
686
687 if (extra_delta_offset64)
688 if (get_msr(cpu, extra_delta_offset64, &t->extra_delta64))
689 return -5;
690
691 if (extra_msr_offset32) {
692 if (get_msr(cpu, extra_msr_offset32, &t->extra_msr32))
693 return -5;
694 t->extra_msr32 &= 0xFFFFFFFF;
695 }
696
668 if (extra_msr_offset64)
669 if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64))
670 return -5;
671
672 /* collect core counters only for 1st thread in core */
673 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
674 return 0;
675

--- 594 unchanged lines hidden (view full) ---

1270
1271 do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model);
1272 do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model);
1273}
1274
1275
1276void usage()
1277{
697 if (extra_msr_offset64)
698 if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64))
699 return -5;
700
701 /* collect core counters only for 1st thread in core */
702 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
703 return 0;
704

--- 594 unchanged lines hidden (view full) ---

1299
1300 do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model);
1301 do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model);
1302}
1303
1304
1305void usage()
1306{
1278 fprintf(stderr, "%s: [-v] [-m msr#] [-M MSR#] [-i interval_sec | command ...]\n",
1307 fprintf(stderr, "%s: [-v][-d MSR#][-D MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n",
1279 progname);
1280 exit(1);
1281}
1282
1283
1284/*
1285 * in /dev/cpu/ return success for names that are numbers
1286 * ie. filter out ".", "..", "microcode".

--- 273 unchanged lines hidden (view full) ---

1560}
1561
1562void cmdline(int argc, char **argv)
1563{
1564 int opt;
1565
1566 progname = argv[0];
1567
1308 progname);
1309 exit(1);
1310}
1311
1312
1313/*
1314 * in /dev/cpu/ return success for names that are numbers
1315 * ie. filter out ".", "..", "microcode".

--- 273 unchanged lines hidden (view full) ---

1589}
1590
1591void cmdline(int argc, char **argv)
1592{
1593 int opt;
1594
1595 progname = argv[0];
1596
1568 while ((opt = getopt(argc, argv, "+cpsvi:m:M:")) != -1) {
1597 while ((opt = getopt(argc, argv, "+cpsvid:D:m:M:")) != -1) {
1569 switch (opt) {
1570 case 'c':
1571 show_core_only++;
1572 break;
1573 case 'p':
1574 show_pkg_only++;
1575 break;
1576 case 's':
1577 summary_only++;
1578 break;
1579 case 'v':
1580 verbose++;
1581 break;
1582 case 'i':
1583 interval_sec = atoi(optarg);
1584 break;
1598 switch (opt) {
1599 case 'c':
1600 show_core_only++;
1601 break;
1602 case 'p':
1603 show_pkg_only++;
1604 break;
1605 case 's':
1606 summary_only++;
1607 break;
1608 case 'v':
1609 verbose++;
1610 break;
1611 case 'i':
1612 interval_sec = atoi(optarg);
1613 break;
1614 case 'd':
1615 sscanf(optarg, "%x", &extra_delta_offset32);
1616 break;
1617 case 'D':
1618 sscanf(optarg, "%x", &extra_delta_offset64);
1619 break;
1585 case 'm':
1586 sscanf(optarg, "%x", &extra_msr_offset32);
1620 case 'm':
1621 sscanf(optarg, "%x", &extra_msr_offset32);
1587 if (verbose > 1)
1588 fprintf(stderr, "msr 0x%X\n", extra_msr_offset32);
1589 break;
1590 case 'M':
1591 sscanf(optarg, "%x", &extra_msr_offset64);
1622 break;
1623 case 'M':
1624 sscanf(optarg, "%x", &extra_msr_offset64);
1592 if (verbose > 1)
1593 fprintf(stderr, "MSR 0x%X\n", extra_msr_offset64);
1594 break;
1595 default:
1596 usage();
1597 }
1598 }
1599}
1600
1601int main(int argc, char **argv)

--- 19 unchanged lines hidden ---
1625 break;
1626 default:
1627 usage();
1628 }
1629 }
1630}
1631
1632int main(int argc, char **argv)

--- 19 unchanged lines hidden ---