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 --- |