xref: /linux/tools/perf/pmu-events/amd_metrics.py (revision c7decec2f2d2ab0366567f9e30c0e1418cece43f)
119eab0efSIan Rogers#!/usr/bin/env python3
219eab0efSIan Rogers# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
319eab0efSIan Rogersimport argparse
4d10ae3a9SIan Rogersimport math
519eab0efSIan Rogersimport os
69c9efc74SIan Rogersfrom typing import Optional
7*82e53e7aSIan Rogersfrom common_metrics import Cycles
86da95e18SIan Rogersfrom metric import (d_ratio, has_event, max, Event, JsonEncodeMetric,
99c9efc74SIan Rogers                    JsonEncodeMetricGroupDescriptions, Literal, LoadEvents,
109c9efc74SIan Rogers                    Metric, MetricGroup, Select)
1119eab0efSIan Rogers
1219eab0efSIan Rogers# Global command line arguments.
1319eab0efSIan Rogers_args = None
149c9efc74SIan Rogers_zen_model: int = 1
15d10ae3a9SIan Rogersinterval_sec = Event("duration_time")
169c9efc74SIan Rogersins = Event("instructions")
179c9efc74SIan Rogerscycles = Event("cycles")
189c9efc74SIan Rogers# Number of CPU cycles scaled for SMT.
199c9efc74SIan Rogerssmt_cycles = Select(cycles / 2, Literal("#smt_on"), cycles)
209c9efc74SIan Rogers
219c9efc74SIan Rogers
2278067ae2SIan Rogersdef AmdBr():
2378067ae2SIan Rogers    def Total() -> MetricGroup:
2478067ae2SIan Rogers        br = Event("ex_ret_brn")
2578067ae2SIan Rogers        br_m_all = Event("ex_ret_brn_misp")
2678067ae2SIan Rogers        br_clr = Event("ex_ret_brn_cond_misp",
2778067ae2SIan Rogers                       "ex_ret_msprd_brnch_instr_dir_msmtch",
2878067ae2SIan Rogers                       "ex_ret_brn_resync")
2978067ae2SIan Rogers
3078067ae2SIan Rogers        br_r = d_ratio(br, interval_sec)
3178067ae2SIan Rogers        ins_r = d_ratio(ins, br)
3278067ae2SIan Rogers        misp_r = d_ratio(br_m_all, br)
3378067ae2SIan Rogers        clr_r = d_ratio(br_clr, interval_sec)
3478067ae2SIan Rogers
3578067ae2SIan Rogers        return MetricGroup("lpm_br_total", [
3678067ae2SIan Rogers            Metric("lpm_br_total_retired",
3778067ae2SIan Rogers                   "The number of branch instructions retired per second.", br_r,
3878067ae2SIan Rogers                   "insn/s"),
3978067ae2SIan Rogers            Metric(
4078067ae2SIan Rogers                "lpm_br_total_mispred",
4178067ae2SIan Rogers                "The number of branch instructions retired, of any type, that were "
4278067ae2SIan Rogers                "not correctly predicted as a percentage of all branch instrucions.",
4378067ae2SIan Rogers                misp_r, "100%"),
4478067ae2SIan Rogers            Metric("lpm_br_total_insn_between_branches",
4578067ae2SIan Rogers                   "The number of instructions divided by the number of branches.",
4678067ae2SIan Rogers                   ins_r, "insn"),
4778067ae2SIan Rogers            Metric("lpm_br_total_insn_fe_resteers",
4878067ae2SIan Rogers                   "The number of resync branches per second.", clr_r, "req/s")
4978067ae2SIan Rogers        ])
5078067ae2SIan Rogers
5178067ae2SIan Rogers    def Taken() -> MetricGroup:
5278067ae2SIan Rogers        br = Event("ex_ret_brn_tkn")
5378067ae2SIan Rogers        br_m_tk = Event("ex_ret_brn_tkn_misp")
5478067ae2SIan Rogers        br_r = d_ratio(br, interval_sec)
5578067ae2SIan Rogers        ins_r = d_ratio(ins, br)
5678067ae2SIan Rogers        misp_r = d_ratio(br_m_tk, br)
5778067ae2SIan Rogers        return MetricGroup("lpm_br_taken", [
5878067ae2SIan Rogers            Metric("lpm_br_taken_retired",
5978067ae2SIan Rogers                   "The number of taken branches that were retired per second.",
6078067ae2SIan Rogers                   br_r, "insn/s"),
6178067ae2SIan Rogers            Metric(
6278067ae2SIan Rogers                "lpm_br_taken_mispred",
6378067ae2SIan Rogers                "The number of retired taken branch instructions that were "
6478067ae2SIan Rogers                "mispredicted as a percentage of all taken branches.", misp_r,
6578067ae2SIan Rogers                "100%"),
6678067ae2SIan Rogers            Metric(
6778067ae2SIan Rogers                "lpm_br_taken_insn_between_branches",
6878067ae2SIan Rogers                "The number of instructions divided by the number of taken branches.",
6978067ae2SIan Rogers                ins_r, "insn"),
7078067ae2SIan Rogers        ])
7178067ae2SIan Rogers
7278067ae2SIan Rogers    def Conditional() -> Optional[MetricGroup]:
7378067ae2SIan Rogers        global _zen_model
7478067ae2SIan Rogers        br = Event("ex_ret_brn_cond", "ex_ret_cond")
7578067ae2SIan Rogers        br_r = d_ratio(br, interval_sec)
7678067ae2SIan Rogers        ins_r = d_ratio(ins, br)
7778067ae2SIan Rogers
7878067ae2SIan Rogers        metrics = [
7978067ae2SIan Rogers            Metric("lpm_br_cond_retired", "Retired conditional branch instructions.",
8078067ae2SIan Rogers                   br_r, "insn/s"),
8178067ae2SIan Rogers            Metric("lpm_br_cond_insn_between_branches",
8278067ae2SIan Rogers                   "The number of instructions divided by the number of conditional "
8378067ae2SIan Rogers                   "branches.", ins_r, "insn"),
8478067ae2SIan Rogers        ]
8578067ae2SIan Rogers        if _zen_model == 2:
8678067ae2SIan Rogers            br_m_cond = Event("ex_ret_cond_misp")
8778067ae2SIan Rogers            misp_r = d_ratio(br_m_cond, br)
8878067ae2SIan Rogers            metrics += [
8978067ae2SIan Rogers                Metric("lpm_br_cond_mispred",
9078067ae2SIan Rogers                       "Retired conditional branch instructions mispredicted as a "
9178067ae2SIan Rogers                       "percentage of all conditional branches.", misp_r, "100%"),
9278067ae2SIan Rogers            ]
9378067ae2SIan Rogers
9478067ae2SIan Rogers        return MetricGroup("lpm_br_cond", metrics)
9578067ae2SIan Rogers
9678067ae2SIan Rogers    def Fused() -> MetricGroup:
9778067ae2SIan Rogers        br = Event("ex_ret_fused_instr", "ex_ret_fus_brnch_inst")
9878067ae2SIan Rogers        br_r = d_ratio(br, interval_sec)
9978067ae2SIan Rogers        ins_r = d_ratio(ins, br)
10078067ae2SIan Rogers        return MetricGroup("lpm_br_cond", [
10178067ae2SIan Rogers            Metric("lpm_br_fused_retired",
10278067ae2SIan Rogers                   "Retired fused branch instructions per second.", br_r, "insn/s"),
10378067ae2SIan Rogers            Metric(
10478067ae2SIan Rogers                "lpm_br_fused_insn_between_branches",
10578067ae2SIan Rogers                "The number of instructions divided by the number of fused "
10678067ae2SIan Rogers                "branches.", ins_r, "insn"),
10778067ae2SIan Rogers        ])
10878067ae2SIan Rogers
10978067ae2SIan Rogers    def Far() -> MetricGroup:
11078067ae2SIan Rogers        br = Event("ex_ret_brn_far")
11178067ae2SIan Rogers        br_r = d_ratio(br, interval_sec)
11278067ae2SIan Rogers        ins_r = d_ratio(ins, br)
11378067ae2SIan Rogers        return MetricGroup("lpm_br_far", [
11478067ae2SIan Rogers            Metric("lpm_br_far_retired", "Retired far control transfers per second.",
11578067ae2SIan Rogers                   br_r, "insn/s"),
11678067ae2SIan Rogers            Metric(
11778067ae2SIan Rogers                "lpm_br_far_insn_between_branches",
11878067ae2SIan Rogers                "The number of instructions divided by the number of far branches.",
11978067ae2SIan Rogers                ins_r, "insn"),
12078067ae2SIan Rogers        ])
12178067ae2SIan Rogers
12278067ae2SIan Rogers    return MetricGroup("lpm_br", [Total(), Taken(), Conditional(), Fused(), Far()],
12378067ae2SIan Rogers                       description="breakdown of retired branch instructions")
12478067ae2SIan Rogers
12578067ae2SIan Rogers
1263563030dSIan Rogersdef AmdCtxSw() -> MetricGroup:
1273563030dSIan Rogers    cs = Event("context\\-switches")
1283563030dSIan Rogers    metrics = [
1293563030dSIan Rogers        Metric("lpm_cs_rate", "Context switches per second",
1303563030dSIan Rogers               d_ratio(cs, interval_sec), "ctxsw/s")
1313563030dSIan Rogers    ]
1323563030dSIan Rogers
1333563030dSIan Rogers    ev = Event("instructions")
1343563030dSIan Rogers    metrics.append(Metric("lpm_cs_instr", "Instructions per context switch",
1353563030dSIan Rogers                          d_ratio(ev, cs), "instr/cs"))
1363563030dSIan Rogers
1373563030dSIan Rogers    ev = Event("cycles")
1383563030dSIan Rogers    metrics.append(Metric("lpm_cs_cycles", "Cycles per context switch",
1393563030dSIan Rogers                          d_ratio(ev, cs), "cycles/cs"))
1403563030dSIan Rogers
1413563030dSIan Rogers    ev = Event("ls_dispatch.pure_ld", "ls_dispatch.ld_dispatch")
1423563030dSIan Rogers    metrics.append(Metric("lpm_cs_loads", "Loads per context switch",
1433563030dSIan Rogers                          d_ratio(ev, cs), "loads/cs"))
1443563030dSIan Rogers
1453563030dSIan Rogers    ev = Event("ls_dispatch.pure_st", "ls_dispatch.store_dispatch")
1463563030dSIan Rogers    metrics.append(Metric("lpm_cs_stores", "Stores per context switch",
1473563030dSIan Rogers                          d_ratio(ev, cs), "stores/cs"))
1483563030dSIan Rogers
1493563030dSIan Rogers    ev = Event("ex_ret_brn_tkn")
1503563030dSIan Rogers    metrics.append(Metric("lpm_cs_br_taken", "Branches taken per context switch",
1513563030dSIan Rogers                          d_ratio(ev, cs), "br_taken/cs"))
1523563030dSIan Rogers
1533563030dSIan Rogers    return MetricGroup("lpm_cs", metrics,
1543563030dSIan Rogers                       description=("Number of context switches per second, instructions "
1553563030dSIan Rogers                                    "retired & core cycles between context switches"))
1563563030dSIan Rogers
1573563030dSIan Rogers
158c4108b95SIan Rogersdef AmdDtlb() -> Optional[MetricGroup]:
159c4108b95SIan Rogers    global _zen_model
160c4108b95SIan Rogers    if _zen_model >= 4:
161c4108b95SIan Rogers        return None
162c4108b95SIan Rogers
163c4108b95SIan Rogers    d_dat = Event("ls_dc_accesses") if _zen_model <= 3 else None
164c4108b95SIan Rogers    d_h4k = Event("ls_l1_d_tlb_miss.tlb_reload_4k_l2_hit")
165c4108b95SIan Rogers    d_hcoal = Event(
166c4108b95SIan Rogers        "ls_l1_d_tlb_miss.tlb_reload_coalesced_page_hit") if _zen_model >= 2 else 0
167c4108b95SIan Rogers    d_h2m = Event("ls_l1_d_tlb_miss.tlb_reload_2m_l2_hit")
168c4108b95SIan Rogers    d_h1g = Event("ls_l1_d_tlb_miss.tlb_reload_1g_l2_hit")
169c4108b95SIan Rogers
170c4108b95SIan Rogers    d_m4k = Event("ls_l1_d_tlb_miss.tlb_reload_4k_l2_miss")
171c4108b95SIan Rogers    d_mcoal = Event(
172c4108b95SIan Rogers        "ls_l1_d_tlb_miss.tlb_reload_coalesced_page_miss") if _zen_model >= 2 else 0
173c4108b95SIan Rogers    d_m2m = Event("ls_l1_d_tlb_miss.tlb_reload_2m_l2_miss")
174c4108b95SIan Rogers    d_m1g = Event("ls_l1_d_tlb_miss.tlb_reload_1g_l2_miss")
175c4108b95SIan Rogers
176c4108b95SIan Rogers    d_w0 = Event("ls_tablewalker.dc_type0") if _zen_model <= 3 else None
177c4108b95SIan Rogers    d_w1 = Event("ls_tablewalker.dc_type1") if _zen_model <= 3 else None
178c4108b95SIan Rogers    walks = d_w0 + d_w1
179c4108b95SIan Rogers    walks_r = d_ratio(walks, interval_sec)
180c4108b95SIan Rogers    ins_w = d_ratio(ins, walks)
181c4108b95SIan Rogers    l1 = d_dat
182c4108b95SIan Rogers    l1_r = d_ratio(l1, interval_sec)
183c4108b95SIan Rogers    l2_hits = d_h4k + d_hcoal + d_h2m + d_h1g
184c4108b95SIan Rogers    l2_miss = d_m4k + d_mcoal + d_m2m + d_m1g
185c4108b95SIan Rogers    l2_r = d_ratio(l2_hits + l2_miss, interval_sec)
186c4108b95SIan Rogers    l1_miss = l2_hits + l2_miss + walks
187c4108b95SIan Rogers    l1_hits = max(l1 - l1_miss, 0)
188c4108b95SIan Rogers    ins_l = d_ratio(ins, l1_miss)
189c4108b95SIan Rogers
190c4108b95SIan Rogers    return MetricGroup("lpm_dtlb", [
191c4108b95SIan Rogers        MetricGroup("lpm_dtlb_ov", [
192c4108b95SIan Rogers            Metric("lpm_dtlb_ov_insn_bt_l1_miss",
193c4108b95SIan Rogers                   "DTLB overview: instructions between l1 misses.", ins_l,
194c4108b95SIan Rogers                   "insns"),
195c4108b95SIan Rogers            Metric("lpm_dtlb_ov_insn_bt_walks",
196c4108b95SIan Rogers                   "DTLB overview: instructions between dtlb page table walks.",
197c4108b95SIan Rogers                   ins_w, "insns"),
198c4108b95SIan Rogers        ]),
199c4108b95SIan Rogers        MetricGroup("lpm_dtlb_l1", [
200c4108b95SIan Rogers            Metric("lpm_dtlb_l1_hits",
201c4108b95SIan Rogers                   "DTLB L1 hits as percentage of all DTLB L1 accesses.",
202c4108b95SIan Rogers                   d_ratio(l1_hits, l1), "100%"),
203c4108b95SIan Rogers            Metric("lpm_dtlb_l1_miss",
204c4108b95SIan Rogers                   "DTLB L1 misses as percentage of all DTLB L1 accesses.",
205c4108b95SIan Rogers                   d_ratio(l1_miss, l1), "100%"),
206c4108b95SIan Rogers            Metric("lpm_dtlb_l1_reqs", "DTLB L1 accesses per second.", l1_r,
207c4108b95SIan Rogers                   "insns/s"),
208c4108b95SIan Rogers        ]),
209c4108b95SIan Rogers        MetricGroup("lpm_dtlb_l2", [
210c4108b95SIan Rogers            Metric("lpm_dtlb_l2_hits",
211c4108b95SIan Rogers                   "DTLB L2 hits as percentage of all DTLB L2 accesses.",
212c4108b95SIan Rogers                   d_ratio(l2_hits, l2_hits + l2_miss), "100%"),
213c4108b95SIan Rogers            Metric("lpm_dtlb_l2_miss",
214c4108b95SIan Rogers                   "DTLB L2 misses as percentage of all DTLB L2 accesses.",
215c4108b95SIan Rogers                   d_ratio(l2_miss, l2_hits + l2_miss), "100%"),
216c4108b95SIan Rogers            Metric("lpm_dtlb_l2_reqs", "DTLB L2 accesses per second.", l2_r,
217c4108b95SIan Rogers                   "insns/s"),
218c4108b95SIan Rogers            MetricGroup("lpm_dtlb_l2_4kb", [
219c4108b95SIan Rogers                Metric(
220c4108b95SIan Rogers                    "lpm_dtlb_l2_4kb_hits",
221c4108b95SIan Rogers                    "DTLB L2 4kb page size hits as percentage of all DTLB L2 4kb "
222c4108b95SIan Rogers                    "accesses.", d_ratio(d_h4k, d_h4k + d_m4k), "100%"),
223c4108b95SIan Rogers                Metric(
224c4108b95SIan Rogers                    "lpm_dtlb_l2_4kb_miss",
225c4108b95SIan Rogers                    "DTLB L2 4kb page size misses as percentage of all DTLB L2 4kb"
226c4108b95SIan Rogers                    "accesses.", d_ratio(d_m4k, d_h4k + d_m4k), "100%")
227c4108b95SIan Rogers            ]),
228c4108b95SIan Rogers            MetricGroup("lpm_dtlb_l2_coalesced", [
229c4108b95SIan Rogers                Metric(
230c4108b95SIan Rogers                    "lpm_dtlb_l2_coal_hits",
231c4108b95SIan Rogers                    "DTLB L2 coalesced page (16kb) hits as percentage of all DTLB "
232c4108b95SIan Rogers                    "L2 coalesced accesses.", d_ratio(d_hcoal,
233c4108b95SIan Rogers                                                      d_hcoal + d_mcoal), "100%"),
234c4108b95SIan Rogers                Metric(
235c4108b95SIan Rogers                    "lpm_dtlb_l2_coal_miss",
236c4108b95SIan Rogers                    "DTLB L2 coalesced page (16kb) misses as percentage of all "
237c4108b95SIan Rogers                    "DTLB L2 coalesced accesses.",
238c4108b95SIan Rogers                    d_ratio(d_mcoal, d_hcoal + d_mcoal), "100%")
239c4108b95SIan Rogers            ]),
240c4108b95SIan Rogers            MetricGroup("lpm_dtlb_l2_2mb", [
241c4108b95SIan Rogers                Metric(
242c4108b95SIan Rogers                    "lpm_dtlb_l2_2mb_hits",
243c4108b95SIan Rogers                    "DTLB L2 2mb page size hits as percentage of all DTLB L2 2mb "
244c4108b95SIan Rogers                    "accesses.", d_ratio(d_h2m, d_h2m + d_m2m), "100%"),
245c4108b95SIan Rogers                Metric(
246c4108b95SIan Rogers                    "lpm_dtlb_l2_2mb_miss",
247c4108b95SIan Rogers                    "DTLB L2 2mb page size misses as percentage of all DTLB L2 "
248c4108b95SIan Rogers                    "accesses.", d_ratio(d_m2m, d_h2m + d_m2m), "100%")
249c4108b95SIan Rogers            ]),
250c4108b95SIan Rogers            MetricGroup("lpm_dtlb_l2_1g", [
251c4108b95SIan Rogers                Metric(
252c4108b95SIan Rogers                    "lpm_dtlb_l2_1g_hits",
253c4108b95SIan Rogers                    "DTLB L2 1gb page size hits as percentage of all DTLB L2 1gb "
254c4108b95SIan Rogers                    "accesses.", d_ratio(d_h1g, d_h1g + d_m1g), "100%"),
255c4108b95SIan Rogers                Metric(
256c4108b95SIan Rogers                    "lpm_dtlb_l2_1g_miss",
257c4108b95SIan Rogers                    "DTLB L2 1gb page size misses as percentage of all DTLB L2 "
258c4108b95SIan Rogers                    "1gb accesses.", d_ratio(d_m1g, d_h1g + d_m1g), "100%")
259c4108b95SIan Rogers            ]),
260c4108b95SIan Rogers        ]),
261c4108b95SIan Rogers        MetricGroup("lpm_dtlb_walks", [
262c4108b95SIan Rogers            Metric("lpm_dtlb_walks_reqs", "DTLB page table walks per second.",
263c4108b95SIan Rogers                   walks_r, "walks/s"),
264c4108b95SIan Rogers        ]),
265c4108b95SIan Rogers    ], description="Data TLB metrics")
266c4108b95SIan Rogers
267c4108b95SIan Rogers
268e596f329SIan Rogersdef AmdItlb():
269e596f329SIan Rogers    global _zen_model
270e596f329SIan Rogers    l2h = Event("bp_l1_tlb_miss_l2_tlb_hit", "bp_l1_tlb_miss_l2_hit")
271e596f329SIan Rogers    l2m = Event("l2_itlb_misses")
272e596f329SIan Rogers    l2r = l2h + l2m
273e596f329SIan Rogers
274e596f329SIan Rogers    itlb_l1_mg = None
275e596f329SIan Rogers    l1m = l2r
276e596f329SIan Rogers    if _zen_model <= 3:
277e596f329SIan Rogers        l1r = Event("ic_fw32")
278e596f329SIan Rogers        l1h = max(l1r - l1m, 0)
279e596f329SIan Rogers        itlb_l1_mg = MetricGroup("lpm_itlb_l1", [
280e596f329SIan Rogers            Metric("lpm_itlb_l1_hits",
281e596f329SIan Rogers                   "L1 ITLB hits as a perecentage of L1 ITLB accesses.",
282e596f329SIan Rogers                   d_ratio(l1h, l1h + l1m), "100%"),
283e596f329SIan Rogers            Metric("lpm_itlb_l1_miss",
284e596f329SIan Rogers                   "L1 ITLB misses as a perecentage of L1 ITLB accesses.",
285e596f329SIan Rogers                   d_ratio(l1m, l1h + l1m), "100%"),
286e596f329SIan Rogers            Metric("lpm_itlb_l1_reqs",
287e596f329SIan Rogers                   "The number of 32B fetch windows transferred from IC pipe to DE "
288e596f329SIan Rogers                   "instruction decoder per second.", d_ratio(
289e596f329SIan Rogers                       l1r, interval_sec),
290e596f329SIan Rogers                   "windows/sec"),
291e596f329SIan Rogers        ])
292e596f329SIan Rogers
293e596f329SIan Rogers    return MetricGroup("lpm_itlb", [
294e596f329SIan Rogers        MetricGroup("lpm_itlb_ov", [
295e596f329SIan Rogers            Metric("lpm_itlb_ov_insn_bt_l1_miss",
296e596f329SIan Rogers                   "Number of instructions between l1 misses", d_ratio(
297e596f329SIan Rogers                       ins, l1m), "insns"),
298e596f329SIan Rogers            Metric("lpm_itlb_ov_insn_bt_l2_miss",
299e596f329SIan Rogers                   "Number of instructions between l2 misses", d_ratio(
300e596f329SIan Rogers                       ins, l2m), "insns"),
301e596f329SIan Rogers        ]),
302e596f329SIan Rogers        itlb_l1_mg,
303e596f329SIan Rogers        MetricGroup("lpm_itlb_l2", [
304e596f329SIan Rogers            Metric("lpm_itlb_l2_hits",
305e596f329SIan Rogers                   "L2 ITLB hits as a percentage of all L2 ITLB accesses.",
306e596f329SIan Rogers                   d_ratio(l2h, l2r), "100%"),
307e596f329SIan Rogers            Metric("lpm_itlb_l2_miss",
308e596f329SIan Rogers                   "L2 ITLB misses as a percentage of all L2 ITLB accesses.",
309e596f329SIan Rogers                   d_ratio(l2m, l2r), "100%"),
310e596f329SIan Rogers            Metric("lpm_itlb_l2_reqs", "ITLB accesses per second.",
311e596f329SIan Rogers                   d_ratio(l2r, interval_sec), "accesses/sec"),
312e596f329SIan Rogers        ]),
313e596f329SIan Rogers    ], description="Instruction TLB breakdown")
314e596f329SIan Rogers
315e596f329SIan Rogers
316fb4c0581SIan Rogersdef AmdLdSt() -> MetricGroup:
317fb4c0581SIan Rogers    ldst_ld = Event("ls_dispatch.pure_ld", "ls_dispatch.ld_dispatch")
318fb4c0581SIan Rogers    ldst_st = Event("ls_dispatch.pure_st", "ls_dispatch.store_dispatch")
319fb4c0581SIan Rogers    ldst_ldc1 = Event(f"{ldst_ld}/cmask=1/")
320fb4c0581SIan Rogers    ldst_stc1 = Event(f"{ldst_st}/cmask=1/")
321fb4c0581SIan Rogers    ldst_ldc2 = Event(f"{ldst_ld}/cmask=2/")
322fb4c0581SIan Rogers    ldst_stc2 = Event(f"{ldst_st}/cmask=2/")
323fb4c0581SIan Rogers    ldst_ldc3 = Event(f"{ldst_ld}/cmask=3/")
324fb4c0581SIan Rogers    ldst_stc3 = Event(f"{ldst_st}/cmask=3/")
325fb4c0581SIan Rogers    ldst_cyc = Event("ls_not_halted_cyc")
326fb4c0581SIan Rogers
327fb4c0581SIan Rogers    ld_rate = d_ratio(ldst_ld, interval_sec)
328fb4c0581SIan Rogers    st_rate = d_ratio(ldst_st, interval_sec)
329fb4c0581SIan Rogers
330fb4c0581SIan Rogers    ld_v1 = max(ldst_ldc1 - ldst_ldc2, 0)
331fb4c0581SIan Rogers    ld_v2 = max(ldst_ldc2 - ldst_ldc3, 0)
332fb4c0581SIan Rogers    ld_v3 = ldst_ldc3
333fb4c0581SIan Rogers
334fb4c0581SIan Rogers    st_v1 = max(ldst_stc1 - ldst_stc2, 0)
335fb4c0581SIan Rogers    st_v2 = max(ldst_stc2 - ldst_stc3, 0)
336fb4c0581SIan Rogers    st_v3 = ldst_stc3
337fb4c0581SIan Rogers
338fb4c0581SIan Rogers    return MetricGroup("lpm_ldst", [
339fb4c0581SIan Rogers        MetricGroup("lpm_ldst_total", [
340fb4c0581SIan Rogers            Metric("lpm_ldst_total_ld", "Number of loads dispatched per second.",
341fb4c0581SIan Rogers                   ld_rate, "insns/sec"),
342fb4c0581SIan Rogers            Metric("lpm_ldst_total_st", "Number of stores dispatched per second.",
343fb4c0581SIan Rogers                   st_rate, "insns/sec"),
344fb4c0581SIan Rogers        ]),
345fb4c0581SIan Rogers        MetricGroup("lpm_ldst_percent_insn", [
346fb4c0581SIan Rogers            Metric("lpm_ldst_percent_insn_ld",
347fb4c0581SIan Rogers                   "Load instructions as a percentage of all instructions.",
348fb4c0581SIan Rogers                   d_ratio(ldst_ld, ins), "100%"),
349fb4c0581SIan Rogers            Metric("lpm_ldst_percent_insn_st",
350fb4c0581SIan Rogers                   "Store instructions as a percentage of all instructions.",
351fb4c0581SIan Rogers                   d_ratio(ldst_st, ins), "100%"),
352fb4c0581SIan Rogers        ]),
353fb4c0581SIan Rogers        MetricGroup("lpm_ldst_ret_loads_per_cycle", [
354fb4c0581SIan Rogers            Metric(
355fb4c0581SIan Rogers                "lpm_ldst_ret_loads_per_cycle_1",
356fb4c0581SIan Rogers                "Load instructions retiring in 1 cycle as a percentage of all "
357fb4c0581SIan Rogers                "unhalted cycles.", d_ratio(ld_v1, ldst_cyc), "100%"),
358fb4c0581SIan Rogers            Metric(
359fb4c0581SIan Rogers                "lpm_ldst_ret_loads_per_cycle_2",
360fb4c0581SIan Rogers                "Load instructions retiring in 2 cycles as a percentage of all "
361fb4c0581SIan Rogers                "unhalted cycles.", d_ratio(ld_v2, ldst_cyc), "100%"),
362fb4c0581SIan Rogers            Metric(
363fb4c0581SIan Rogers                "lpm_ldst_ret_loads_per_cycle_3",
364fb4c0581SIan Rogers                "Load instructions retiring in 3 or more cycles as a percentage"
365fb4c0581SIan Rogers                "of all unhalted cycles.", d_ratio(ld_v3, ldst_cyc), "100%"),
366fb4c0581SIan Rogers        ]),
367fb4c0581SIan Rogers        MetricGroup("lpm_ldst_ret_stores_per_cycle", [
368fb4c0581SIan Rogers            Metric(
369fb4c0581SIan Rogers                "lpm_ldst_ret_stores_per_cycle_1",
370fb4c0581SIan Rogers                "Store instructions retiring in 1 cycle as a percentage of all "
371fb4c0581SIan Rogers                "unhalted cycles.", d_ratio(st_v1, ldst_cyc), "100%"),
372fb4c0581SIan Rogers            Metric(
373fb4c0581SIan Rogers                "lpm_ldst_ret_stores_per_cycle_2",
374fb4c0581SIan Rogers                "Store instructions retiring in 2 cycles as a percentage of all "
375fb4c0581SIan Rogers                "unhalted cycles.", d_ratio(st_v2, ldst_cyc), "100%"),
376fb4c0581SIan Rogers            Metric(
377fb4c0581SIan Rogers                "lpm_ldst_ret_stores_per_cycle_3",
378fb4c0581SIan Rogers                "Store instructions retiring in 3 or more cycles as a percentage"
379fb4c0581SIan Rogers                "of all unhalted cycles.", d_ratio(st_v3, ldst_cyc), "100%"),
380fb4c0581SIan Rogers        ]),
381fb4c0581SIan Rogers        MetricGroup("lpm_ldst_insn_bt", [
382fb4c0581SIan Rogers            Metric("lpm_ldst_insn_bt_ld", "Number of instructions between loads.",
383fb4c0581SIan Rogers                   d_ratio(ins, ldst_ld), "insns"),
384fb4c0581SIan Rogers            Metric("lpm_ldst_insn_bt_st", "Number of instructions between stores.",
385fb4c0581SIan Rogers                   d_ratio(ins, ldst_st), "insns"),
386fb4c0581SIan Rogers        ])
387fb4c0581SIan Rogers    ], description="Breakdown of load/store instructions")
388fb4c0581SIan Rogers
389fb4c0581SIan Rogers
3909c9efc74SIan Rogersdef AmdUpc() -> Metric:
3919c9efc74SIan Rogers    ops = Event("ex_ret_ops", "ex_ret_cops")
3929c9efc74SIan Rogers    upc = d_ratio(ops, smt_cycles)
3939c9efc74SIan Rogers    return Metric("lpm_upc", "Micro-ops retired per core cycle (higher is better)",
3949c9efc74SIan Rogers                  upc, "uops/cycle")
395d10ae3a9SIan Rogers
396d10ae3a9SIan Rogers
3976da95e18SIan Rogersdef Idle() -> Metric:
3986da95e18SIan Rogers    cyc = Event("msr/mperf/")
3996da95e18SIan Rogers    tsc = Event("msr/tsc/")
4006da95e18SIan Rogers    low = max(tsc - cyc, 0)
4016da95e18SIan Rogers    return Metric(
4026da95e18SIan Rogers        "lpm_idle",
4036da95e18SIan Rogers        "Percentage of total wallclock cycles where CPUs are in low power state (C1 or deeper sleep state)",
4046da95e18SIan Rogers        d_ratio(low, tsc), "100%")
4056da95e18SIan Rogers
4066da95e18SIan Rogers
407d10ae3a9SIan Rogersdef Rapl() -> MetricGroup:
408d10ae3a9SIan Rogers    """Processor socket power consumption estimate.
409d10ae3a9SIan Rogers
410d10ae3a9SIan Rogers    Use events from the running average power limit (RAPL) driver.
411d10ae3a9SIan Rogers    """
412d10ae3a9SIan Rogers    # Watts = joules/second
413d10ae3a9SIan Rogers    # Currently only energy-pkg is supported by AMD:
414d10ae3a9SIan Rogers    # https://lore.kernel.org/lkml/20220105185659.643355-1-eranian@google.com/
415d10ae3a9SIan Rogers    pkg = Event("power/energy\\-pkg/")
416d10ae3a9SIan Rogers    cond_pkg = Select(pkg, has_event(pkg), math.nan)
417d10ae3a9SIan Rogers    scale = 2.3283064365386962890625e-10
418d10ae3a9SIan Rogers    metrics = [
419d10ae3a9SIan Rogers        Metric("lpm_cpu_power_pkg", "",
420d10ae3a9SIan Rogers               d_ratio(cond_pkg * scale, interval_sec), "Watts"),
421d10ae3a9SIan Rogers    ]
422d10ae3a9SIan Rogers
423d10ae3a9SIan Rogers    return MetricGroup("lpm_cpu_power", metrics,
424d10ae3a9SIan Rogers                       description="Processor socket power consumption estimates")
425d10ae3a9SIan Rogers
42619eab0efSIan Rogers
4275ecb1622SIan Rogersdef UncoreL3():
4285ecb1622SIan Rogers    acc = Event("l3_lookup_state.all_coherent_accesses_to_l3",
4295ecb1622SIan Rogers                "l3_lookup_state.all_l3_req_typs")
4305ecb1622SIan Rogers    miss = Event("l3_lookup_state.l3_miss",
4315ecb1622SIan Rogers                 "l3_comb_clstr_state.request_miss")
4325ecb1622SIan Rogers    acc = max(acc, miss)
4335ecb1622SIan Rogers    hits = acc - miss
4345ecb1622SIan Rogers
4355ecb1622SIan Rogers    return MetricGroup("lpm_l3", [
4365ecb1622SIan Rogers        Metric("lpm_l3_accesses", "L3 victim cache accesses",
4375ecb1622SIan Rogers               d_ratio(acc, interval_sec), "accesses/sec"),
4385ecb1622SIan Rogers        Metric("lpm_l3_hits", "L3 victim cache hit rate",
4395ecb1622SIan Rogers               d_ratio(hits, acc), "100%"),
4405ecb1622SIan Rogers        Metric("lpm_l3_miss", "L3 victim cache miss rate", d_ratio(miss, acc),
4415ecb1622SIan Rogers               "100%"),
4425ecb1622SIan Rogers    ], description="L3 cache breakdown per CCX")
4435ecb1622SIan Rogers
4445ecb1622SIan Rogers
44519eab0efSIan Rogersdef main() -> None:
44619eab0efSIan Rogers    global _args
4479c9efc74SIan Rogers    global _zen_model
44819eab0efSIan Rogers
44919eab0efSIan Rogers    def dir_path(path: str) -> str:
45019eab0efSIan Rogers        """Validate path is a directory for argparse."""
45119eab0efSIan Rogers        if os.path.isdir(path):
45219eab0efSIan Rogers            return path
45319eab0efSIan Rogers        raise argparse.ArgumentTypeError(
45419eab0efSIan Rogers            f'\'{path}\' is not a valid directory')
45519eab0efSIan Rogers
45619eab0efSIan Rogers    parser = argparse.ArgumentParser(description="AMD perf json generator")
45719eab0efSIan Rogers    parser.add_argument(
45819eab0efSIan Rogers        "-metricgroups", help="Generate metricgroups data", action='store_true')
45919eab0efSIan Rogers    parser.add_argument("model", help="e.g. amdzen[123]")
46019eab0efSIan Rogers    parser.add_argument(
46119eab0efSIan Rogers        'events_path',
46219eab0efSIan Rogers        type=dir_path,
46319eab0efSIan Rogers        help='Root of tree containing architecture directories containing json files'
46419eab0efSIan Rogers    )
46519eab0efSIan Rogers    _args = parser.parse_args()
46619eab0efSIan Rogers
4676bd6c5efSIan Rogers    directory = f"{_args.events_path}/x86/{_args.model}/"
4686bd6c5efSIan Rogers    LoadEvents(directory)
4696bd6c5efSIan Rogers
4709c9efc74SIan Rogers    _zen_model = int(_args.model[6:])
4719c9efc74SIan Rogers
472d10ae3a9SIan Rogers    all_metrics = MetricGroup("", [
47378067ae2SIan Rogers        AmdBr(),
4743563030dSIan Rogers        AmdCtxSw(),
475c4108b95SIan Rogers        AmdDtlb(),
476e596f329SIan Rogers        AmdItlb(),
477fb4c0581SIan Rogers        AmdLdSt(),
4789c9efc74SIan Rogers        AmdUpc(),
479*82e53e7aSIan Rogers        Cycles(),
4806da95e18SIan Rogers        Idle(),
481d10ae3a9SIan Rogers        Rapl(),
4825ecb1622SIan Rogers        UncoreL3(),
483d10ae3a9SIan Rogers    ])
48419eab0efSIan Rogers
48519eab0efSIan Rogers    if _args.metricgroups:
48619eab0efSIan Rogers        print(JsonEncodeMetricGroupDescriptions(all_metrics))
48719eab0efSIan Rogers    else:
48819eab0efSIan Rogers        print(JsonEncodeMetric(all_metrics))
48919eab0efSIan Rogers
49019eab0efSIan Rogers
49119eab0efSIan Rogersif __name__ == '__main__':
49219eab0efSIan Rogers    main()
493