# 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<br>[GitHub](https://github.com/jsrz)<br>[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?
After completing this Learning Path, you'll be able to perform the following tasks:
- 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'll need the following prerequisites:
- 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

**How do I know the system counter example produced a valid measurement?**

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.

**Which Arm instructions are used to access system registers for counting?**

Use `MRS` to read a system register and `MSR` to write a system register. These two instructions are sufficient for the system counter example.

**PAPI cannot find its headers or libraries at build or runtime. What should I check?**

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`.

<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.

<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.
