# How to use the Arm Performance Monitoring Unit and System Counter

## In this learning path

- [Introduction](https://learn.arm.com/learning-paths/servers-and-cloud-computing/arm_pmu/)
- [Counter access options](https://learn.arm.com/learning-paths/servers-and-cloud-computing/arm_pmu/access_options/)
- [Use a system counter](https://learn.arm.com/learning-paths/servers-and-cloud-computing/arm_pmu/assembly/)
- [Use PAPI for counting](https://learn.arm.com/learning-paths/servers-and-cloud-computing/arm_pmu/papi/)
- [Use perf_event_open for counting](https://learn.arm.com/learning-paths/servers-and-cloud-computing/arm_pmu/perf_event_open/)
- [Next Steps](https://learn.arm.com/learning-paths/servers-and-cloud-computing/arm_pmu/_next-steps/)

## About this Learning Path

| Skill level:                | Advanced                    |
|-----------------------------|-----------------------------|
| Reading time:               | 1 hr 30 min                 |
| Last updated:               | 29 Jun 2026                 |

| Author:                     | Julio Suarez, Arm [GitHub](https://github.com/jsrz) [LinkedIn](https://linkedin.com/in/juliosuarez) |
|-----------------------------|-----------------------------|
| Arm IP:                     | [Neoverse](https://support.arm.com/?tab=compute-ip&Product%20Type=Infrastructure%20Processors)        |
| Tags:                       | [Performance and Architecture](https://learn.arm.com/tag/performance-and-architecture), [Linux](https://learn.arm.com/tag/linux), [PAPI](https://learn.arm.com/tag/papi), [perf](https://learn.arm.com/tag/perf), [Assembly](https://learn.arm.com/tag/assembly), [GCC](https://learn.arm.com/tag/gcc), [Runbook](https://learn.arm.com/tag/runbook) |

### Who is this for?

This is an advanced topic for software developers who want to instrument hardware event counters or the system counter in software applications.

### What will you learn?

Upon completion of this Learning Path, you will be able to:

- Understand different options for accessing counters from user space
- Use the system counter to measure time in code
- Use PAPI to instrument event counters in code
- Use the Linux `perf_event_open` system call to instrument event counters in code

### Prerequisites

Before starting, you will need the following:

- An Arm computer running Linux. A bare metal or cloud metal instance is best because they expose more counters. You can use a virtual machine (VM), but fewer counters may be available. These instructions have been tested on the `a1.metal` instance type.

### Summary

You’ll access Arm hardware event counters and the system counter from user space on Linux using the PMU. First, you’ll distinguish software and hardware events, then use a minimal assembly approach with `MRS` and `MSR` to read the system counter and measure time around a function. You’ll then instrument event counters with PAPI, including environment configuration and user-space counter access. You’ll finish with two C examples that use `perf_event_open` to read either a single counter or a group of counters without multiplexing. By the end, you’ll build and run working code that returns measurable counter values suitable for basic performance instrumentation on Arm systems.

### Frequently asked questions

<details>
<summary>How do I know the system counter example produced a valid measurement?</summary>
The program should report a positive difference in system counter ticks between the two reads that bracket the target function. A zero or negative value usually means the reads are not placed correctly around the region being measured.
</details>

<details>
<summary>Which Arm instructions are used to access system registers for counting?</summary>
Use `MRS` to read a system register and `MSR` to write a system register. These two instructions are sufficient for the system counter example.
</details>

<details>
<summary>PAPI cannot find its headers or libraries at build or runtime. What should I check?</summary>
Set `PAPI_DIR` to the location where PAPI is installed. Depending on your system, you might also need `LD_LIBRARY_PATH` to include `$PAPI_DIR/lib`.
</details>

<details>
<summary>What should I do before using PAPI or `perf_event_open` to access counters from user space?</summary>
Run the `sudo` command in the steps that writes the recommended value to the file under `/proc/sys/kernel`. This enables user-space access to the counters for the examples.
</details>

<details>
<summary>When using `perf_event_open`, which example should I use to read multiple counters at once?</summary>
Use the group example to read several counters together without multiplexing. The single-counter example configures just one event, and `perf_event_open` in this Learning Path does not support multiplexing.
</details>
