1 Using TopDown metrics 2 --------------------- 3 4 TopDown metrics break apart performance bottle 5 1 it is typical to get metrics on retiring, ba 6 bound, and backend bound. Higher levels provid 7 level 1 bottlenecks, such as at level 2: core 8 heavy operations, light operations, branch mis 9 clears, fetch latency and fetch bandwidth. For 10 11 perf stat --topdown implements this using avai 12 per architecture. 13 14 % perf stat -a --topdown -I1000 15 # time % tma_retiring % tma_b 16 1.001141351 11.5 17 2.006141972 13.4 18 3.010162040 12.9 19 4.014009311 12.5 20 5.017838554 11.8 21 5.704818971 14.0 22 ... 23 24 New Topdown features in Intel Ice Lake 25 ====================================== 26 27 With Ice Lake CPUs the TopDown metrics are dir 28 fixed counters and do not require generic coun 29 to collect TopDown always in addition to other 30 31 Using TopDown through RDPMC in applications on 32 ============================================== 33 34 For more fine grained measurements it can be u 35 access the new directly from user space. This 36 but drastically lowers overhead. 37 38 On Ice Lake, there is a new fixed counter 3: S 39 "pipeline SLOTS" (cycles multiplied by core is 40 metric register that reports slots ratios for 41 categories. 42 43 The metrics counter is CPU model specific and 44 CPUs. 45 46 Example code 47 ============ 48 49 Library functions to do the functionality desc 50 is also available in libjevents [4] 51 52 The application opens a group with fixed count 53 metric event, and allow user programs to read 54 55 Fixed counter 3 is mapped to a pseudo event ev 56 so the perf_event_attr structure should be ini 57 { .config = 0x0400, .type = PERF_TYPE_RAW } 58 The metric events are mapped to the pseudo eve 59 For example, the perf_event_attr structure can 60 { .config = 0x8000, .type = PERF_TYPE_RAW } fo 61 The Fixed counter 3 must be the leader of the 62 63 #include <linux/perf_event.h> 64 #include <sys/mman.h> 65 #include <sys/syscall.h> 66 #include <unistd.h> 67 68 /* Provide own perf_event_open stub because gl 69 __attribute__((weak)) 70 int perf_event_open(struct perf_event_attr *at 71 int cpu, int group_fd, uns 72 { 73 return syscall(__NR_perf_event_open, a 74 } 75 76 /* Open slots counter file descriptor for curr 77 struct perf_event_attr slots = { 78 .type = PERF_TYPE_RAW, 79 .size = sizeof(struct perf_event_attr) 80 .config = 0x400, 81 .exclude_kernel = 1, 82 }; 83 84 int slots_fd = perf_event_open(&slots, 0, -1, 85 if (slots_fd < 0) 86 ... error ... 87 88 /* Memory mapping the fd permits _rdpmc calls 89 void *slots_p = mmap(0, getpagesize(), PROT_RE 90 if (!slot_p) 91 .... error ... 92 93 /* 94 * Open metrics event file descriptor for curr 95 * Set slots event as the leader of the group. 96 */ 97 struct perf_event_attr metrics = { 98 .type = PERF_TYPE_RAW, 99 .size = sizeof(struct perf_event_attr) 100 .config = 0x8000, 101 .exclude_kernel = 1, 102 }; 103 104 int metrics_fd = perf_event_open(&metrics, 0, 105 if (metrics_fd < 0) 106 ... error ... 107 108 /* Memory mapping the fd permits _rdpmc calls 109 void *metrics_p = mmap(0, getpagesize(), PROT_ 110 if (!metrics_p) 111 ... error ... 112 113 Note: the file descriptors returned by the per 114 mapped to permit calls to the _rdpmd instructi 115 by writing the /sys/devices/cpu/rdpmc sysfs no 116 117 The RDPMC instruction (or _rdpmc compiler intr 118 to read slots and the topdown metrics at diffe 119 120 #include <stdint.h> 121 #include <x86intrin.h> 122 123 #define RDPMC_FIXED (1 << 30) /* ret 124 #define RDPMC_METRIC (1 << 29) /* ret 125 126 #define FIXED_COUNTER_SLOTS 3 127 #define METRIC_COUNTER_TOPDOWN_L1_L2 0 128 129 static inline uint64_t read_slots(void) 130 { 131 return _rdpmc(RDPMC_FIXED | FIXED_COUN 132 } 133 134 static inline uint64_t read_metrics(void) 135 { 136 return _rdpmc(RDPMC_METRIC | METRIC_CO 137 } 138 139 Then the program can be instrumented to read t 140 points. 141 142 It's not a good idea to do this with too short 143 as the parallelism and overlap in the CPU prog 144 cause too much measurement inaccuracy. For exa 145 individual basic blocks is definitely too fine 146 147 _rdpmc calls should not be mixed with reading 148 through system calls, as the kernel will reset 149 call. 150 151 Decoding metrics values 152 ======================= 153 154 The value reported by read_metrics() contains 155 that represent a scaled ratio that represent t 156 All four fields add up to 0xff (= 100%) 157 158 The binary ratios in the metric value can be c 159 160 #define GET_METRIC(m, i) (((m) >> (i*8)) & 0xf 161 162 /* L1 Topdown metric events */ 163 #define TOPDOWN_RETIRING(val) ((float)GET_ME 164 #define TOPDOWN_BAD_SPEC(val) ((float)GET_ME 165 #define TOPDOWN_FE_BOUND(val) ((float)GET_ME 166 #define TOPDOWN_BE_BOUND(val) ((float)GET_ME 167 168 /* 169 * L2 Topdown metric events. 170 * Available on Sapphire Rapids and later plat 171 */ 172 #define TOPDOWN_HEAVY_OPS(val) ((floa 173 #define TOPDOWN_BR_MISPREDICT(val) ((floa 174 #define TOPDOWN_FETCH_LAT(val) ((floa 175 #define TOPDOWN_MEM_BOUND(val) ((floa 176 177 and then converted to percent for printing. 178 179 The ratios in the metric accumulate for the ti 180 is enabled. For measuring programs it is often 181 specific sections. For this it is needed to de 182 183 This can be done by scaling the metrics with t 184 read at the same time. 185 186 Then it's possible to take deltas of these slo 187 measured at different points, and determine th 188 for that time period. 189 190 slots_a = read_slots(); 191 metric_a = read_metrics(); 192 193 ... larger code region ... 194 195 slots_b = read_slots() 196 metric_b = read_metrics() 197 198 # compute scaled metrics for measureme 199 retiring_slots_a = GET_METRIC(metric_a 200 bad_spec_slots_a = GET_METRIC(metric_a 201 fe_bound_slots_a = GET_METRIC(metric_a 202 be_bound_slots_a = GET_METRIC(metric_a 203 204 # compute delta scaled metrics between 205 retiring_slots = GET_METRIC(metric_b, 206 bad_spec_slots = GET_METRIC(metric_b, 207 fe_bound_slots = GET_METRIC(metric_b, 208 be_bound_slots = GET_METRIC(metric_b, 209 210 Later the individual ratios of L1 metric event 211 be recreated from these counts. 212 213 slots_delta = slots_b - slots_a 214 retiring_ratio = (float)retiring_slots 215 bad_spec_ratio = (float)bad_spec_slots 216 fe_bound_ratio = (float)fe_bound_slots 217 be_bound_ratio = (float)be_bound_slots 218 219 printf("Retiring %.2f%% Bad Speculatio 220 retiring_ratio * 100., 221 bad_spec_ratio * 100., 222 fe_bound_ratio * 100., 223 be_bound_ratio * 100.); 224 225 The individual ratios of L2 metric events for 226 recreated from L1 and L2 metric counters. (Ava 227 later platforms) 228 229 # compute scaled metrics for measureme 230 heavy_ops_slots_a = GET_METRIC(metric_ 231 br_mispredict_slots_a = GET_METRIC(met 232 fetch_lat_slots_a = GET_METRIC(metric_ 233 mem_bound_slots_a = GET_METRIC(metric_ 234 235 # compute delta scaled metrics between 236 heavy_ops_slots = GET_METRIC(metric_b, 237 br_mispredict_slots = GET_METRIC(metri 238 fetch_lat_slots = GET_METRIC(metric_b, 239 mem_bound_slots = GET_METRIC(metric_b, 240 241 slots_delta = slots_b - slots_a 242 heavy_ops_ratio = (float)heavy_ops_slo 243 light_ops_ratio = retiring_ratio - hea 244 245 br_mispredict_ratio = (float)br_mispre 246 machine_clears_ratio = bad_spec_ratio 247 248 fetch_lat_ratio = (float)fetch_lat_slo 249 fetch_bw_ratio = fe_bound_ratio - fetc 250 251 mem_bound_ratio = (float)mem_bound_slo 252 core_bound_ratio = be_bound_ratio - me 253 254 printf("Heavy Operations %.2f%% Light 255 "Branch Mispredict %.2f%% Machi 256 "Fetch Latency %.2f%% Fetch Ban 257 "Mem Bound %.2f%% Core Bound %. 258 heavy_ops_ratio * 100., 259 light_ops_ratio * 100., 260 br_mispredict_ratio * 100., 261 machine_clears_ratio * 100., 262 fetch_lat_ratio * 100., 263 fetch_bw_ratio * 100., 264 mem_bound_ratio * 100., 265 core_bound_ratio * 100.); 266 267 Resetting metrics counters 268 ========================== 269 270 Since the individual metrics are only 8bit the 271 short regions over time because the number of 272 fraction bit shrinks. So the counters need to 273 274 When using the kernel perf API the kernel rese 275 So as long as the reading is at reasonable int 276 seconds) the precision is good. 277 278 When using perf stat it is recommended to alwa 279 with no longer interval than a few seconds 280 281 perf stat -I 1000 --topdown ... 282 283 For user programs using RDPMC directly the cou 284 be reset explicitly using ioctl: 285 286 ioctl(perf_fd, PERF_EVENT_IOC_RESET, 0 287 288 This "opens" a new measurement period. 289 290 A program using RDPMC for TopDown should sched 291 regularly, as in every few seconds. 292 293 Limits on Intel Ice Lake 294 ======================== 295 296 Four pseudo TopDown metric events are exposed 297 topdown-retiring, topdown-bad-spec, topdown-fe 298 They can be used to collect the TopDown value 299 rules: 300 - All the TopDown metric events must be in a g 301 - The SLOTS event must be the leader of the gr 302 - The PERF_FORMAT_GROUP flag must be applied f 303 events 304 305 The SLOTS event and the TopDown metric events 306 a sampling read group. Since the SLOTS event m 307 group, the second event of the group is the sa 308 For example, perf record -e '{slots, $sampling 309 310 Extension on Intel Sapphire Rapids Server 311 ========================================= 312 The metrics counter is extended to support TMA 313 The lower half of the register is the TMA leve 314 The upper half is also divided into four 8-bit 315 metrics. Four more TopDown metric events are e 316 topdown-heavy-ops, topdown-br-mispredict, topd 317 topdown-mem-bound. 318 319 Each of the new level 2 metrics in the upper h 320 corresponding level 1 metric in the lower half 321 other four level 2 metrics by subtracting corr 322 323 Light_Operations = Retiring - Heavy_Operat 324 Machine_Clears = Bad_Speculation - Branch_ 325 Fetch_Bandwidth = Frontend_Bound - Fetch_L 326 Core_Bound = Backend_Bound - Memory_Bound 327 328 TPEBS in TopDown 329 ================ 330 331 TPEBS (Timed PEBS) is one of the new Intel PMU 332 Rapids microarchitecture. The TPEBS feature ad 333 in the Basic Info group of the PEBS record. It 334 retirement of the previous instruction to the 335 Please refer to Section 8.4.1 of "Intel® Arch 336 Programming Reference" for more details about 337 extends PEBS record, sampling with weight opti 338 retire_latency value. 339 340 perf record -e event_name -W ... 341 342 In the most recent release of TMA, the metrics 343 values in some of the metrics’ formulas on p 344 For previous generations that do not support T 345 predefined per processor family by the hardwar 346 of workloads in execution environments, retire 347 time are more accurate. Therefore, new TMA met 348 more accurate performance analysis results. 349 350 To support TPEBS in TMA metrics, a new modifie 351 capture retire_latency value of required event 352 with perf record. The retire_latency value wou 353 Currently, this feature is supported through p 354 355 perf stat -M metric_name --record-tpeb 356 357 358 359 [1] https://software.intel.com/en-us/top-down- 360 [2] https://sites.google.com/site/analysismeth 361 [3] https://perf.wiki.kernel.org/index.php/Top 362 [4] https://github.com/andikleen/pmu-tools/tre
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.