Skip to content

Commit 5bb7b87

Browse files
updates
1 parent 1e33f3d commit 5bb7b87

3 files changed

Lines changed: 31 additions & 24 deletions

File tree

content/learning-paths/servers-and-cloud-computing/false-sharing-arm-spe/_index.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
---
22
title: Analyze cache behavior with Perf C2C on Arm
33

4-
draft: true
5-
cascade:
6-
draft: true
4+
5+
76

87
minutes_to_complete: 15
98

10-
who_is_this_for: This topic is for developers who want to optimize cache access patterns on Arm servers using Perf C2C.
9+
who_is_this_for: This topic is for performance-oriented developers working on Arm-based cloud or server systems who want to optimize memory access patterns and investigate cache inefficiencies using Perf C2C and Arm SPE.
1110

1211
learning_objectives:
13-
- Avoid false sharing in C++ using memory alignment.
12+
- Identify and fix false sharing issues using Perf C2C, a cache line analysis tool.
1413
- Enable and use the Arm Statistical Profiling Extension (SPE) on Linux systems.
1514
- Investigate cache line performance with Perf C2C.
1615

content/learning-paths/servers-and-cloud-computing/false-sharing-arm-spe/how-to-1.md

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,35 @@ weight: 2
55
### FIXED, DO NOT MODIFY
66
layout: learningpathall
77
---
8-
98
## Introduction to the Arm Statistical Profiling Extension (SPE)
109

11-
Standard performance tracing relies on counting completed instructions, capturing only architectural instructions without revealing the actual memory addresses, pipeline latencies, or considering micro-operations in flight. Moreover, the “skid” phenomenon where events are falsely attributed to later instructions can mislead developers.
10+
Traditional Linux performance profiling tools often rely on retired instruction counts, which lack visibility into memory addresses, cache latencies, and micro-operation behavior. Moreover, the “skid” phenomenon where events are falsely attributed to later instructions can mislead developers.
1211

1312
SPE integrates sampling directly into the CPU pipeline, triggering on individual micro-operations rather than retired instructions, thereby eliminating skid and blind spots. Each SPE sample record includes relevant metadata, such as data addresses, per-µop pipeline latency, triggered PMU event masks, and the memory hierarchy source, enabling fine-grained and precise cache analysis.
1413

15-
This enables software developers to tune user-space software for characteristics such as memory latency and cache accesses. Importantly, cache statistics are enabled with the Linux Perf cache-to-cache (C2C) utility.
14+
SPE helps developers optimize user-space applications by showing where cache latency or memory access delays are happening. Importantly, cache statistics are enabled with the Linux Perf cache-to-cache (C2C) utility.
1615

17-
Please refer to the [Arm SPE white paper](https://developer.arm.com/documentation/109429/latest/) for more details.
16+
To learn more, check out the [Arm SPE white paper](https://developer.arm.com/documentation/109429/latest/) for more information.
1817

1918
In this Learning Path, you will use SPE and Perf C2C to diagnose a cache issue for an application running on a Neoverse server.
2019

21-
## False sharing within the cache
20+
## What is false sharing and why should I care about it?
21+
22+
In large-scale, multithreaded applications, false sharing can degrade performance by introducing hundreds of unnecessary cache line invalidations per second - often with no visible red flags in the source code.
23+
24+
Even when two threads touch entirely separate variables, modern processors move data in fixed-size cache lines (nominally 64-bytes). If those distinct variables happen to occupy bytes within the same line, every time one thread writes its variable the core’s cache must gain exclusive ownership of the whole line, forcing the other core’s copy to be invalidated.
2225

23-
Even when two threads touch entirely separate variables, modern processors move data in fixed-size cache lines (nominally 64-bytes). If those distinct variables happen to occupy bytes within the same line, every time one thread writes its variable the core’s cache must gain exclusive ownership of the whole line, forcing the other core’s copy to be invalidated. The second thread, still working on its own variable, then triggers a coherence miss to fetch the line back, and the ping-pong pattern repeats. Please see the illustration below, taken from the Arm SPE white paper, for a visual explanation.
26+
The second thread, still working on its own variable, then triggers a coherence miss to fetch the line back, and the ping-pong pattern repeats. See the illustration below, taken from the Arm SPE white paper, for a visual explanation.
2427

25-
![false_sharing_diagram](./false_sharing_diagram.png)
28+
![false_sharing_diagram alt-text#center](./false_sharing_diagram.png "Two threads on separate cores alternately gain exclusive access to the same cache line.")
2629

2730
Because false sharing hides behind ordinary writes, the easiest time to eliminate it is while reading or refactoring the source code by padding or realigning the offending variables before compilation. In large, highly concurrent codebases, however, data structures are often accessed through several layers of abstraction, and many threads touch memory via indirection, so the subtle cache-line overlap may not surface until profiling or performance counters reveal unexpected coherence misses.
2831

2932
From a source-code perspective nothing is “shared,” but at the hardware level both variables are implicitly coupled by their physical location.
3033

3134
## Alignment to cache lines
3235

33-
In C++11, you can manually specify the alignment of an object with the `alignas` specifier. For example, the C++11 source code below manually aligns the the `struct` every 64 bytes (typical cache line size on a modern processor). This ensures that each instance of `AlignedType` is on a separate cache line.
36+
In C++11, you can manually specify the alignment of an object with the `alignas` specifier. For example, the C++11 source code below manually aligns the `struct` every 64 bytes (typical cache line size on a modern processor). This ensures that each instance of `AlignedType` is on a separate cache line.
3437

3538
```cpp
3639
#include <atomic>
@@ -43,7 +46,7 @@ struct alignas(64) AlignedType {
4346

4447

4548
int main() {
46-
// If we create four atomic integers like this, there's a high probability
49+
// If you create four atomic integers like this, there's a high probability
4750
// they'll wind up next to each other in memory
4851
std::atomic<int> a;
4952
std::atomic<int> b;
@@ -74,9 +77,9 @@ int main() {
7477
}
7578
```
7679

77-
The example output below shows the variables e, f, g and h occur at least 64-bytes apart in the byte-addressable architecture. Whereas variables a, b, c and d occur 8 bytes apart, occupying the same cache line.
80+
The example output below shows the variables e, f, g and h occur at least 64 bytes apart in the byte-addressable architecture. Whereas variables a, b, c, and d occur 8 bytes apart, occupying the same cache line.
7881

79-
Although this is a contrived example, in a production workload there may be several layers of indirection that unintentionally result in false sharing. For these complex cases, to understand the root cause you will use Perf C2C.
82+
Although this is a contrived example, in a production workload there might be several layers of indirection that unintentionally result in false sharing. For these complex cases, to understand the root cause you will use Perf C2C.
8083

8184
```output
8285
Without Alignment can occupy same cache line
@@ -96,4 +99,9 @@ Address of AlignedType g - 0xffffeb6c60c0
9699
Address of AlignedType h - 0xffffeb6c6080
97100
```
98101

99-
Continue to the next section to learn how to set up a system to run Perf C2C.
102+
## Summary
103+
104+
In this section, you learned what Arm SPE is and why it’s a game-changer for performance profiling. You also saw how a subtle issue like false sharing can slow down multithreaded code — and how to avoid it using alignment in C++.
105+
106+
Next up: you’ll set up your environment and get ready to run Perf C2C on a real application.
107+

content/learning-paths/servers-and-cloud-computing/false-sharing-arm-spe/how-to-2.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ uname -r
2323

2424
The output includes the CPU type and kernel release version:
2525

26-
```ouput
26+
```output
2727
Model name: Neoverse-N1
2828
6.1.134-152.225.amzn2023.aarch64
2929
```
@@ -43,7 +43,7 @@ Run the following command to confirm if the SPE kernel module is loaded:
4343
sudo modprobe arm_spe_pmu
4444
```
4545

46-
If the module is not loaded (blank output), SPE may still be available.
46+
If the module is not loaded (blank output), SPE might still be available.
4747

4848
Run this command to check if SPE is included in the kernel:
4949

@@ -63,11 +63,11 @@ If the output is blank then SPE is not available.
6363

6464
You can install and run a Python script named Sysreport to summarize your system's performance profiling capabilities.
6565

66-
Refer to [Get ready for performance analysis with Sysreport](https://learn.arm.com/learning-paths/servers-and-cloud-computing/sysreport/) to learn how to install and run it.
66+
See [Get ready for performance analysis with Sysreport](https://learn.arm.com/learning-paths/servers-and-cloud-computing/sysreport/) to learn how to install and run it.
6767

6868
Look at the Sysreport output and confirm SPE is available by checking the `perf sampling` field.
6969

70-
If the printed value is SPE then SPE is available.
70+
If the printed value is SPE, then SPE is available.
7171

7272
```output
7373
...
@@ -105,9 +105,9 @@ Assign capabilities to Perf by running:
105105
sudo setcap cap_perfmon,cap_sys_ptrace,cap_sys_admin+ep $(which perf)
106106
```
107107

108-
If `arm_spe` is not available because of your system configuration or if you don't have PMU permission, the `perf c2c` command will fail.
108+
If `arm_spe` is not available because of your system configuration or if you don't have PMU permission, the `perf c2c` command fails.
109109

110-
To confirm Perf can access SPE run:
110+
To confirm Perf can access SPE, run:
111111

112112
```bash
113113
perf c2c record
@@ -120,7 +120,7 @@ failed: memory events not supported
120120
```
121121

122122
{{% notice Note %}}
123-
If you are unable to use SPE it may be a restriction based on your cloud instance size or operating system.
123+
If you are unable to use SPE it might be a restriction based on your cloud instance size or operating system.
124124

125125
Generally, access to a full server (also known as metal instances) with a relatively new kernel is needed for Arm SPE support.
126126

0 commit comments

Comments
 (0)