Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

topdown: Created a component for interfacing with Intel's PERF_METRICS MSR #286

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

willowec
Copy link
Contributor

@willowec willowec commented Nov 17, 2024

Pull Request Description

This PR adds a component that reads Intel's PERF_METRICS Model Specific Register (MSR) and extracts topdown micro-architecture analysis metrics from it, converting those metrics to percentages automatically for ease of use. For example:

$ ./utils/papi_command_line TOPDOWN_RETIRING_PERC TOPDOWN_BAD_SPEC_PERC \ 
    TOPDOWN_FE_BOUND_PERC TOPDOWN_BE_BOUND_PERC

Successfully added: TOPDOWN_RETIRING_PERC
Successfully added: TOPDOWN_BAD_SPEC_PERC
Successfully added: TOPDOWN_FE_BOUND_PERC
Successfully added: TOPDOWN_BE_BOUND_PERC

TOPDOWN_RETIRING_PERC : 	20.784 %
TOPDOWN_BAD_SPEC_PERC : 	0.000 %
TOPDOWN_FE_BOUND_PERC : 	1.961 %
TOPDOWN_BE_BOUND_PERC : 	76.863 %

----------------------------------

Tested systems:

System Name Family/Model/Stepping papi_native_avail papi_component_avail papi_command_line Topdown tests
Raptor Lake-S/HX B0 0x6/0xb7/0x1

While this PR only adds support for RaptorLake, all IA32 systems that support the PERF_METRICS Model Specific Register should be able to be added without much hassle.

The primary motivation for this PR is to add a user-friendly, fast, and obvious way to collect topdown metrics with PAPI. I have made some attempts to support topdown metrics in the perf_event component (see PR #238), but found that the necessary changes would be quite hacky and still deliver a frustratingly obscure user experience.

Author Checklist

  • Description
    Why this PR exists. Reference all relevant information, including background, issues, test failures, etc
  • Commits
    Commits are self contained and only do one thing
    Commits have a header of the form: module: short description
    Commits have a body (whenever relevant) containing a detailed description of the addressed problem and its solution
  • Tests
    The PR needs to pass all the tests

@willowec
Copy link
Contributor Author

If desired, I can add entries for all of the models I am aware of that support the PERF_METRICS MSR, but I am only able to test on RaptorLake.

@willowec willowec marked this pull request as draft December 3, 2024 16:20
…S MSR

Add a component that collects Intel's topdown metrics from the
PERF_METRICS MSR and automatically converts the raw metric values to
user-consumable percentages.

The intent of this component is to provide an intuitive interface for
accessing topdown metrics on the supported processors.

Tested on a RaptorLake-S/HX machine (family/model/stepping
0x6/0xb7/0x1). To add other supported architectures the switch statment
in _topdown_init_component() should be populated for the architecture's
model number, whether it supports level 2 topdown metrics, and in the
case of a heterogeneous processor what core type it must be run on.
@willowec
Copy link
Contributor Author

willowec commented Dec 3, 2024

This force push was just to standardize the use of tabs for indenting in the component

@willowec willowec marked this pull request as ready for review December 3, 2024 16:31
@willowec willowec marked this pull request as draft December 4, 2024 15:33
While the offical Software Developer Manual only lists the availability
of the PERF_METRICS MSR for three architectures, we can use the
'perfmon' repository maintained by Intel to discover what architectures
support the MSR (repo here: https://github.com/intel/perfmon).

Architectures that the repository demonstrates support the events
'PERF_METRICS.BACKEND_BOUND', 'PERF_METRICS.FRONTEND_BOUND', etc. must
support the topdown level 1 metrics of the PERF_METRICS MSR. Similarly,
the presence of the events 'PERF_METRICS.FETCH_LATENCY',
'PERF_METRICS.MEMORY_BOUND', etc. demonstrates support for topdown L2
metrics in the PERF_METRICS MSR. By cross-referencing the architecture
names in the perfmon repository with their DisplayFamily/DisplayModel
values in Table 2-1 of volume 4 of the IA32 SDM, we can add support for
the following architectures:

- Rocket Lake
- Ice Lake (icl & icx)
- Tiger Lake
- Sapphire Rapids
- Meteor Lake (redwood cove p-core only)
- Alder Lake (golden cove p-core only)
- Granite Rapids
- Everald Rapids

None of these additional architectures have been tested with
the topdown component yet. While Arrow Lake is shown to support L1 &
L2 metrics in the prefmon repository, its FamilyModel is not yet
available in the IA32 SDM so it has not been added.
All of Intel's heterogeneous CPUs that support the PERF_METRICS MSR only
support it for their performance (p-core) cores. This means that if a
program that is being measured using the topdown component in PAPI
happens to be rescheduled to a e-core during its runtime, PAPI will
segfault.

To fix this, add a check in _topdown_start() and _topdown_stop() to exit
gracefully if the core affinity of the process has changed to an
unsupported core type.
@willowec willowec marked this pull request as ready for review December 11, 2024 19:39
@willowec
Copy link
Contributor Author

Alright, the component is complete and ready for review.

Previously, the x86intrin.h header file had been included in order to
provide definitions for _rdpmc(). However, this has caused the github
actions testing compilation of the component on ARM systems to fail.
Therefore, remove the include and add a manual definition for _rdpmc()
taken from the perf_event component.
@willowec
Copy link
Contributor Author

Now that the component is passing all of the CI tests, it is actually ready for review.

@Treece-Burgess Treece-Burgess added update-components PRs adding a new component to PAPI status-ready-for-review PR is ready to be reviewed labels Dec 19, 2024
To prevent programs using the topdown component on heterogeneous
processors that only supply the PERF_METRICS MSR on some of their cores
from segfaulting due to trying to read the MSR after being moved to an
unsupported core type, the topdown component periodically checks it is
on a supported core and exits if not.

Previously, this check occured at the start of PAPI_start and PAPI_stop.
After writing a script that starts a program being calipered with the
topdown component and moves it to an unsupported core after a random
amount of time, for N=100,000 tests the heterogeneous checks failed to
prevent a segmentation fault 0.08% of the time. This patch moves the
heterogeneous checks to occur only directly before the rdpmc calls,
resulting in cleaner code and a reduced segfault prevention failure
rate of 0.064%.

While it is frustrating that the failure rate is non-zero, since there
appears to be no way to tell a process to ignore changes to its
affinity, I believe there to be no perfect solution at this time.
@willowec
Copy link
Contributor Author

willowec commented Jan 8, 2025

Just put up a commit that tightens the checks preventing segmentation faults due to unexpected process affinity changes on heterogeneous processors.

I was considering trying to change the behavior to record the percentage of runtime where the process was on a supported core type and use that to indicate how much the results should be trusted instead of simply exiting if the process is found to be on an unsupported core. However, now that I have thought about it more deeply I am not sure if that is even possible. The way metrics are collected requires that the program be on a supported core throughout both PAPI_start and PAPI_stop, so if the program started on a supported core and moved to an unsupported core between those calls there would be no way to extract meaningful results. Furthermore, if the program is moved to an unsupported core and back in between the two calls, there is no way to record that happening without an interrupt that is triggered on affinity change. I guess for now just exiting with an error message makes the most sense.

@willowec willowec marked this pull request as draft January 22, 2025 15:43
@willowec
Copy link
Contributor Author

willowec commented Jan 22, 2025

Converting to a draft while I investigate the feasibility of using rseq to completely eliminate segfaults on heterogeneous processors

Previously, the topdown component calculated metrics by taking the
difference of the metrics before and the metrics after the calculated
code block using Equation 1:

M% = (Mb*Sb/255 - Ma*Sa/255) / (Sb - Sa) * 100                   (1)

where Mx are the raw bytes of the metric before and after the calipered
code block and Sx are the slots. However, if Sa = 0 this simplifies to

M% = Mb/255 * 100                                                (2)

Therefore it is sufficient to simply reset the PERF_METRICS MSR and
SLOTS during PAPI_start() and then use Equation 2 in PAPI_stop, reducing
the number of dangerous rdpmc calls, reducing overhead, and simplifying
the code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status-ready-for-review PR is ready to be reviewed update-components PRs adding a new component to PAPI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants