diff options
| author | Len Brown <len.brown@intel.com> | 2012-06-04 00:56:40 -0400 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2012-07-19 22:26:14 -0400 |
| commit | c98d5d9444732a032bc55d1a496bfa8439da9199 (patch) | |
| tree | a6d3ba319f3c575c21f8bb7cc757c928135b6cbd | |
| parent | d3514abcf5b896a3a66d8b7c960a0018a52ebc2c (diff) | |
tools/power: turbostat v2 - re-write for efficiency
Measuring large profoundly-idle configurations
requires turbostat to be more lightweight.
Otherwise, the operation of turbostat itself
can interfere with the measurements.
This re-write makes turbostat topology aware.
Hardware is accessed in "topology order".
Redundant hardware accesses are deleted.
Redundant output is deleted.
Also, output is buffered and
local RDTSC use replaces remote MSR access for TSC.
From a feature point of view, the output
looks different since redundant figures are absent.
Also, there are now -c and -p options -- to restrict
output to the 1st thread in each core, and the 1st
thread in each package, respectively. This is helpful
to reduce output on big systems, where more detail
than the "-s" system summary is desired.
Finally, periodic mode output is now on stdout, not stderr.
Turbostat v2 is also slightly more robust in
handling run-time CPU online/offline events,
as it now checks the actual map of on-line cpus rather
than just the total number of on-line cpus.
Signed-off-by: Len Brown <len.brown@intel.com>
| -rw-r--r-- | tools/power/x86/turbostat/Makefile | 1 | ||||
| -rw-r--r-- | tools/power/x86/turbostat/turbostat.8 | 77 | ||||
| -rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 1329 |
3 files changed, 868 insertions, 539 deletions
diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile index fd8e1f1297aa..f85649554191 100644 --- a/tools/power/x86/turbostat/Makefile +++ b/tools/power/x86/turbostat/Makefile | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | turbostat : turbostat.c | 1 | turbostat : turbostat.c |
| 2 | CFLAGS += -Wall | ||
| 2 | 3 | ||
| 3 | clean : | 4 | clean : |
| 4 | rm -f turbostat | 5 | rm -f turbostat |
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index adf175f61496..74e44507dfe9 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 | |||
| @@ -27,7 +27,11 @@ supports an "invariant" TSC, plus the APERF and MPERF MSRs. | |||
| 27 | on processors that additionally support C-state residency counters. | 27 | on processors that additionally support C-state residency counters. |
| 28 | 28 | ||
| 29 | .SS Options | 29 | .SS Options |
| 30 | The \fB-s\fP option prints only a 1-line summary for each sample interval. | 30 | The \fB-s\fP option limits output to a 1-line system summary for each interval. |
| 31 | .PP | ||
| 32 | The \fB-c\fP option limits output to the 1st thread in each core. | ||
| 33 | .PP | ||
| 34 | The \fB-p\fP option limits output to the 1st thread in each package. | ||
| 31 | .PP | 35 | .PP |
| 32 | The \fB-v\fP option increases verbosity. | 36 | The \fB-v\fP option increases verbosity. |
| 33 | .PP | 37 | .PP |
| @@ -65,19 +69,19 @@ Subsequent rows show per-CPU statistics. | |||
| 65 | .nf | 69 | .nf |
| 66 | [root@x980]# ./turbostat | 70 | [root@x980]# ./turbostat |
| 67 | cor CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 | 71 | cor CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 |
| 68 | 0.60 1.63 3.38 2.91 0.00 96.49 0.00 76.64 | 72 | 0.09 1.62 3.38 1.83 0.32 97.76 1.26 83.61 |
| 69 | 0 0 0.59 1.62 3.38 4.51 0.00 94.90 0.00 76.64 | 73 | 0 0 0.15 1.62 3.38 10.23 0.05 89.56 1.26 83.61 |
| 70 | 0 6 1.13 1.64 3.38 3.97 0.00 94.90 0.00 76.64 | 74 | 0 6 0.05 1.62 3.38 10.34 |
| 71 | 1 2 0.08 1.62 3.38 0.07 0.00 99.85 0.00 76.64 | 75 | 1 2 0.03 1.62 3.38 0.07 0.05 99.86 |
| 72 | 1 8 0.03 1.62 3.38 0.12 0.00 99.85 0.00 76.64 | 76 | 1 8 0.03 1.62 3.38 0.06 |
| 73 | 2 4 0.01 1.62 3.38 0.06 0.00 99.93 0.00 76.64 | 77 | 2 4 0.21 1.62 3.38 0.10 1.49 98.21 |
| 74 | 2 10 0.04 1.62 3.38 0.02 0.00 99.93 0.00 76.64 | 78 | 2 10 0.02 1.62 3.38 0.29 |
| 75 | 8 1 2.85 1.62 3.38 11.71 0.00 85.44 0.00 76.64 | 79 | 8 1 0.04 1.62 3.38 0.04 0.08 99.84 |
| 76 | 8 7 1.98 1.62 3.38 12.58 0.00 85.44 0.00 76.64 | 80 | 8 7 0.01 1.62 3.38 0.06 |
| 77 | 9 3 0.36 1.62 3.38 0.71 0.00 98.93 0.00 76.64 | 81 | 9 3 0.53 1.62 3.38 0.10 0.20 99.17 |
| 78 | 9 9 0.09 1.62 3.38 0.98 0.00 98.93 0.00 76.64 | 82 | 9 9 0.02 1.62 3.38 0.60 |
| 79 | 10 5 0.03 1.62 3.38 0.09 0.00 99.87 0.00 76.64 | 83 | 10 5 0.01 1.62 3.38 0.02 0.04 99.92 |
| 80 | 10 11 0.07 1.62 3.38 0.06 0.00 99.87 0.00 76.64 | 84 | 10 11 0.02 1.62 3.38 0.02 |
| 81 | .fi | 85 | .fi |
| 82 | .SH SUMMARY EXAMPLE | 86 | .SH SUMMARY EXAMPLE |
| 83 | The "-s" option prints the column headers just once, | 87 | The "-s" option prints the column headers just once, |
| @@ -86,9 +90,10 @@ and then the one line system summary for each sample interval. | |||
| 86 | .nf | 90 | .nf |
| 87 | [root@x980]# ./turbostat -s | 91 | [root@x980]# ./turbostat -s |
| 88 | %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 | 92 | %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 |
| 89 | 0.61 1.89 3.38 5.95 0.00 93.44 0.00 66.33 | 93 | 0.23 1.67 3.38 2.00 0.30 97.47 1.07 82.12 |
| 90 | 0.52 1.62 3.38 6.83 0.00 92.65 0.00 61.11 | 94 | 0.10 1.62 3.38 1.87 2.25 95.77 12.02 72.60 |
| 91 | 0.62 1.92 3.38 5.47 0.00 93.91 0.00 67.31 | 95 | 0.20 1.64 3.38 1.98 0.11 97.72 0.30 83.36 |
| 96 | 0.11 1.70 3.38 1.86 1.81 96.22 9.71 74.90 | ||
| 92 | .fi | 97 | .fi |
| 93 | .SH VERBOSE EXAMPLE | 98 | .SH VERBOSE EXAMPLE |
| 94 | The "-v" option adds verbosity to the output: | 99 | The "-v" option adds verbosity to the output: |
| @@ -120,30 +125,28 @@ until ^C while the other CPUs are mostly idle: | |||
| 120 | [root@x980 lenb]# ./turbostat cat /dev/zero > /dev/null | 125 | [root@x980 lenb]# ./turbostat cat /dev/zero > /dev/null |
| 121 | ^C | 126 | ^C |
| 122 | cor CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 | 127 | cor CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 |
| 123 | 8.63 3.64 3.38 14.46 0.49 76.42 0.00 0.00 | 128 | 8.86 3.61 3.38 15.06 31.19 44.89 0.00 0.00 |
| 124 | 0 0 0.34 3.36 3.38 99.66 0.00 0.00 0.00 0.00 | 129 | 0 0 1.46 3.22 3.38 16.84 29.48 52.22 0.00 0.00 |
| 125 | 0 6 99.96 3.64 3.38 0.04 0.00 0.00 0.00 0.00 | 130 | 0 6 0.21 3.06 3.38 18.09 |
| 126 | 1 2 0.14 3.50 3.38 1.75 2.04 96.07 0.00 0.00 | 131 | 1 2 0.53 3.33 3.38 2.80 46.40 50.27 |
| 127 | 1 8 0.38 3.57 3.38 1.51 2.04 96.07 0.00 0.00 | 132 | 1 8 0.89 3.47 3.38 2.44 |
| 128 | 2 4 0.01 2.65 3.38 0.06 0.00 99.93 0.00 0.00 | 133 | 2 4 1.36 3.43 3.38 9.04 23.71 65.89 |
| 129 | 2 10 0.03 2.12 3.38 0.04 0.00 99.93 0.00 0.00 | 134 | 2 10 0.18 2.86 3.38 10.22 |
| 130 | 8 1 0.91 3.59 3.38 35.27 0.92 62.90 0.00 0.00 | 135 | 8 1 0.04 2.87 3.38 99.96 0.01 0.00 |
| 131 | 8 7 1.61 3.63 3.38 34.57 0.92 62.90 0.00 0.00 | 136 | 8 7 99.72 3.63 3.38 0.27 |
| 132 | 9 3 0.04 3.38 3.38 0.20 0.00 99.76 0.00 0.00 | 137 | 9 3 0.31 3.21 3.38 7.64 56.55 35.50 |
| 133 | 9 9 0.04 3.29 3.38 0.20 0.00 99.76 0.00 0.00 | 138 | 9 9 0.08 2.95 3.38 7.88 |
| 134 | 10 5 0.03 3.08 3.38 0.12 0.00 99.85 0.00 0.00 | 139 | 10 5 1.42 3.43 3.38 2.14 30.99 65.44 |
| 135 | 10 11 0.05 3.07 3.38 0.10 0.00 99.85 0.00 0.00 | 140 | 10 11 0.16 2.88 3.38 3.40 |
| 136 | 4.907015 sec | ||
| 137 | |||
| 138 | .fi | 141 | .fi |
| 139 | Above the cycle soaker drives cpu6 up 3.6 Ghz turbo limit | 142 | Above the cycle soaker drives cpu7 up its 3.6 Ghz turbo limit |
| 140 | while the other processors are generally in various states of idle. | 143 | while the other processors are generally in various states of idle. |
| 141 | 144 | ||
| 142 | Note that cpu0 is an HT sibling sharing core0 | 145 | Note that cpu1 and cpu7 are HT siblings within core8. |
| 143 | with cpu6, and thus it is unable to get to an idle state | 146 | As cpu7 is very busy, it prevents its sibling, cpu1, |
| 144 | deeper than c1 while cpu6 is busy. | 147 | from entering a c-state deeper than c1. |
| 145 | 148 | ||
| 146 | Note that turbostat reports average GHz of 3.64, while | 149 | Note that turbostat reports average GHz of 3.63, while |
| 147 | the arithmetic average of the GHz column above is lower. | 150 | the arithmetic average of the GHz column above is lower. |
| 148 | This is a weighted average, where the weight is %c0. ie. it is the total number of | 151 | This is a weighted average, where the weight is %c0. ie. it is the total number of |
| 149 | un-halted cycles elapsed per time divided by the number of CPUs. | 152 | un-halted cycles elapsed per time divided by the number of CPUs. |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 16de7ad4850f..b815a12159b2 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
| @@ -67,92 +67,119 @@ double bclk; | |||
| 67 | unsigned int show_pkg; | 67 | unsigned int show_pkg; |
| 68 | unsigned int show_core; | 68 | unsigned int show_core; |
| 69 | unsigned int show_cpu; | 69 | unsigned int show_cpu; |
| 70 | unsigned int show_pkg_only; | ||
| 71 | unsigned int show_core_only; | ||
| 72 | char *output_buffer, *outp; | ||
| 70 | 73 | ||
| 71 | int aperf_mperf_unstable; | 74 | int aperf_mperf_unstable; |
| 72 | int backwards_count; | 75 | int backwards_count; |
| 73 | char *progname; | 76 | char *progname; |
| 74 | 77 | ||
| 75 | int num_cpus; | 78 | cpu_set_t *cpu_present_set, *cpu_affinity_set; |
| 76 | cpu_set_t *cpu_present_set, *cpu_mask; | 79 | size_t cpu_present_setsize, cpu_affinity_setsize; |
| 77 | size_t cpu_present_setsize, cpu_mask_size; | 80 | |
| 78 | 81 | struct thread_data { | |
| 79 | struct counters { | 82 | unsigned long long tsc; |
| 80 | unsigned long long tsc; /* per thread */ | 83 | unsigned long long aperf; |
| 81 | unsigned long long aperf; /* per thread */ | 84 | unsigned long long mperf; |
| 82 | unsigned long long mperf; /* per thread */ | 85 | unsigned long long c1; /* derived */ |
| 83 | unsigned long long c1; /* per thread (calculated) */ | 86 | unsigned long long extra_msr; |
| 84 | unsigned long long c3; /* per core */ | 87 | unsigned int cpu_id; |
| 85 | unsigned long long c6; /* per core */ | 88 | unsigned int flags; |
| 86 | unsigned long long c7; /* per core */ | 89 | #define CPU_IS_FIRST_THREAD_IN_CORE 0x2 |
| 87 | unsigned long long pc2; /* per package */ | 90 | #define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4 |
| 88 | unsigned long long pc3; /* per package */ | 91 | } *thread_even, *thread_odd; |
| 89 | unsigned long long pc6; /* per package */ | 92 | |
| 90 | unsigned long long pc7; /* per package */ | 93 | struct core_data { |
| 91 | unsigned long long extra_msr; /* per thread */ | 94 | unsigned long long c3; |
| 92 | int pkg; | 95 | unsigned long long c6; |
| 93 | int core; | 96 | unsigned long long c7; |
| 94 | int cpu; | 97 | unsigned int core_id; |
| 95 | struct counters *next; | 98 | } *core_even, *core_odd; |
| 96 | }; | 99 | |
| 97 | 100 | struct pkg_data { | |
| 98 | struct counters *cnt_even; | 101 | unsigned long long pc2; |
| 99 | struct counters *cnt_odd; | 102 | unsigned long long pc3; |
| 100 | struct counters *cnt_delta; | 103 | unsigned long long pc6; |
| 101 | struct counters *cnt_average; | 104 | unsigned long long pc |
