You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/learning-paths/servers-and-cloud-computing/memory-subsystem/_index.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ draft: true
7
7
cascade:
8
8
draft: true
9
9
10
-
minutes_to_complete: 90
10
+
minutes_to_complete: 60
11
11
12
12
who_is_this_for: This is an advanced topic for software developers and performance engineers who want to understand and characterize the CPU-side memory subsystem of Arm Linux systems.
Copy file name to clipboardExpand all lines: content/learning-paths/servers-and-cloud-computing/memory-subsystem/comparative-analysis.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@ You now have a complete set of memory subsystem measurements for each of your te
12
12
13
13
## Collect all memory benchmarks in one command
14
14
15
-
Throughout this Learning Path, you ran individual ASCT benchmarks. To characterize a new system from scratch, run all memory benchmarks at once.
15
+
Throughout the previous sections, you ran individual ASCT benchmarks. To characterize a new system from scratch, run all memory benchmarks at once.
16
16
17
17
Run all tests and save the results.
18
18
@@ -198,7 +198,7 @@ echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governo
198
198
199
199
## Adapting this analysis to any Arm Linux system
200
200
201
-
This Learning Path used AWS Graviton instances as examples, but the methodology works on any Arm Linux machine with a NUMA-enabled kernel. To adapt it:
201
+
The examples here used AWS Graviton instances, but the methodology works on any Arm Linux machine with a NUMA-enabled kernel. To adapt it:
202
202
203
203
1.**Install ASCT** on the target system following the [install guide](/install-guides/asct/).
204
204
2.**Run all memory benchmarks**: `sudo asct run memory loaded-latency --format=csv --output-dir results_$(hostname)`
@@ -208,7 +208,7 @@ This Learning Path used AWS Graviton instances as examples, but the methodology
208
208
209
209
## What you've accomplished
210
210
211
-
In this Learning Path you:
211
+
In this section you:
212
212
- Identified the topology and cache hierarchy of Arm Linux systems using `sysfs` and `asct system-info`
213
213
- Measured cache and memory latency with the ASCT `latency-sweep` benchmark
214
214
- Measured single-core streaming bandwidth with `bandwidth-sweep`
Copy file name to clipboardExpand all lines: content/learning-paths/servers-and-cloud-computing/memory-subsystem/multicore-bandwidth.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ layout: learningpathall
8
8
9
9
## Why multi-core bandwidth matters
10
10
11
-
A single core rarely saturates the shared resources in a modern Arm system. The L3 cache, memory controllers, and interconnect fabric are designed to serve many cores simultaneously. Multi-core bandwidth testing reveals how these shared resources scale — or saturate — as more cores become active.
11
+
A single core rarely saturates the shared resources in a modern Arm system. The L3 cache, memory controllers, and interconnect fabric are designed to serve many cores simultaneously. Multi-core bandwidth testing reveals how these shared resources scale, or saturate, as more cores become active.
12
12
13
13
## Measure multi-core bandwidth and loaded latency with ASCT
14
14
@@ -56,7 +56,7 @@ Peak memory bandwidth
56
56
57
57
Several patterns emerge from the traffic type comparison:
58
58
59
-
-**All Reads** gives the highest throughput because reads are simpler for the memory controller — no write-back or write-allocate overhead.
59
+
-**All Reads** gives the highest throughput because reads are simpler for the memory controller, with no write-back or write-allocate overhead.
60
60
-**Read-write mixes** reduce throughput progressively as the write ratio increases. Writes require the controller to alternate between read and write bus turnarounds, and each write involves a cache line allocation and potential eviction.
61
61
62
62
Graviton4 with DDR5 delivers roughly 2.7x the peak all-reads bandwidth of Graviton2 with DDR4 (465.5 vs 169.6 GB/s). The Graviton4 output also includes a non-temporal traffic pattern (2:1 Rd-Wr Non-Temporal), which bypasses the cache on writes and can be more efficient for pure streaming workloads.
@@ -65,7 +65,7 @@ Compare the "All Reads" figure with the theoretical peak bandwidth reported by `
65
65
66
66
## Loaded latency
67
67
68
-
The `loaded-latency` benchmark measures how memory latency changes as other cores generate increasing bandwidth pressure. It pins a latency-measuring thread on the last core of the first NUMA node and uses the remaining cores to generate background memory traffic. The traffic intensity is controlled by interleaving memory reads with different numbers of no-operation (NOP) instructions — more NOPs means less bandwidth pressure.
68
+
The `loaded-latency` benchmark measures how memory latency changes as other cores generate increasing bandwidth pressure. It pins a latency-measuring thread on the last core of the first NUMA node and uses the remaining cores to generate background memory traffic. The traffic intensity is controlled by interleaving memory reads with different numbers of no-operation (NOP) instructions. More NOPs means less bandwidth pressure.
69
69
70
70
{{% notice Note %}}
71
71
The `loaded-latency` benchmark takes several minutes to complete because it runs multiple measurement phases at different traffic levels.
Copy file name to clipboardExpand all lines: content/learning-paths/servers-and-cloud-computing/memory-subsystem/pointer-chase-latency.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -78,7 +78,7 @@ Your actual numbers will differ. The important pattern is the steps in latency a
78
78
79
79
Graviton2 uses Neoverse N1 cores with a 64 KB L1D, 1 MB private L2, and a 32 MB shared L3. DRAM is DDR4.
80
80
81
-
Graviton4 uses Neoverse V2 cores with a larger 2 MB private L2 and a shared L3. The V2 microarchitecture has an improved cache pipeline. DDR5 provides higher bandwidth than DDR4, but its unloaded DRAM latency is slightly higher, which is reflected in the measured results.
81
+
Graviton4 uses Neoverse V2 cores with a larger 2 MB private L2 and a shared L3. The Neoverse V2 microarchitecture has an improved cache pipeline. DDR5 provides higher bandwidth than DDR4, but its unloaded DRAM latency is slightly higher, which is reflected in the measured results.
82
82
83
83
The boundaries where latency changes correspond closely to the cache sizes you discovered in the previous section. This is the cross-validation that makes the analysis credible: latency transitions align with known hardware boundaries.
Copy file name to clipboardExpand all lines: content/learning-paths/servers-and-cloud-computing/memory-subsystem/system-overview.md
+15-4Lines changed: 15 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,11 +6,13 @@ weight: 2
6
6
layout: learningpathall
7
7
---
8
8
9
+
Memory behavior is one of the primary determinants of compute performance for memory-bound applications. The CPU-side memory subsystem, including caches, interconnects, and DRAM, directly shapes that behavior. Understanding latency, streaming bandwidth, and how caches and cores share resources is essential for diagnosing bottlenecks and tuning software on Arm servers.
10
+
9
11
## Identify CPU, cache, and NUMA topology
10
12
11
13
Before you can characterize a memory subsystem, you need to understand how the system is organized. The number of cores, how they are grouped into clusters, the DRAM type, and the operating system all influence memory behavior. Knowing this topology helps interpret benchmark results.
12
14
13
-
This Learning Path uses two example AWS Graviton instances:
15
+
The examples throughout use two AWS Graviton instances:
14
16
15
17
- AWS Graviton2, `c6g.16xlarge`, instance with Arm Neoverse N1 cores.
16
18
- AWS Graviton4, `c8g.16xlarge`, instance with Arm Neoverse V2 cores.
@@ -19,6 +21,13 @@ Both systems run Ubuntu 24.04 with 64 CPUs, 128 GB RAM, and 32 GB of storage.
19
21
20
22
These are just examples, and you can follow the same steps on any Arm Linux system.
21
23
24
+
If you want to follow along with the same instances, create two EC2 instances using the AWS console or CLI:
25
+
26
+
- A `c6g.16xlarge` instance running Ubuntu 24.04 (Graviton2)
27
+
- A `c8g.16xlarge` instance running Ubuntu 24.04 (Graviton4)
28
+
29
+
Make sure both instances are accessible via SSH before continuing.
30
+
22
31
## Collect basic system information
23
32
24
33
Start by setting a descriptive hostname on each system. This makes it easier to identify results later when you use `$(hostname)` in output directory names.
@@ -46,7 +55,7 @@ uname -a && cat /etc/os-release
46
55
Both systems have the same software:
47
56
48
57
```output
49
-
Linux ip-10-0-0-35 6.17.0-1007-aws #7~24.04.1-Ubuntu SMP Thu Jan 22 20:37:30 UTC 2026 aarch64 aarch64 aarch64 GNU/Linux
58
+
Linux graviton2-c6g 6.17.0-1007-aws #7~24.04.1-Ubuntu SMP Thu Jan 22 20:37:30 UTC 2026 aarch64 aarch64 aarch64 GNU/Linux
50
59
PRETTY_NAME="Ubuntu 24.04.4 LTS"
51
60
NAME="Ubuntu"
52
61
VERSION_ID="24.04"
@@ -68,7 +77,7 @@ Print the CPU information:
68
77
lscpu
69
78
```
70
79
71
-
Pay close attention to the `lscpu` output — it gives you the CPU model, the number of cores, threads per core, sockets, and NUMA node configuration. Here is an example from a Graviton2 instance:
80
+
Pay close attention to the `lscpu` output. It gives you the CPU model, the number of cores, threads per core, sockets, and NUMA node configuration. Here is an example from a Graviton2 instance:
72
81
73
82
```output
74
83
Architecture: aarch64
@@ -127,9 +136,11 @@ NUMA:
127
136
128
137
The two systems span two generations of Arm Neoverse server cores. Graviton2 uses Neoverse N1 cores with private 1 MB L2 caches per core and a 32 MB shared L3. Graviton4 uses Neoverse V2 cores with 2 MB private L2 caches per core and a 36 MB shared L3. These differences in cache sizes and memory technology directly impact the memory latency, bandwidth, and scaling behavior you observe in later benchmarks.
129
138
139
+
Notice that the Neoverse V2 `Flags` field is significantly longer than Neoverse N1. This reflects the newer Arm architecture: V2 is based on Armv9, which adds extensions like SVE2, BF16, and I8MM that are absent on the Armv8-based N1.
140
+
130
141
## Check DRAM configuration
131
142
132
-
On AWS Graviton instances, `dmidecode` is unavailable because the hypervisor does not expose SMBIOS memory data to guests. You can confirm the memory size with `free -h`:
0 commit comments