Skip to content

Commit f7094a4

Browse files
Streamlining
1 parent fce20ad commit f7094a4

4 files changed

Lines changed: 34 additions & 71 deletions

File tree

content/learning-paths/cross-platform/simd-loops/1-about.md

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,17 @@ layout: learningpathall
88

99
Writing high-performance software on Arm often means using single-instruction, multiple-data (SIMD) technologies. Many developers start with NEON, a familiar fixed-width vector extension. As Arm architectures evolve, so do the SIMD capabilities available to you.
1010

11-
This Learning Path uses the **Scalable Vector Extension (SVE)** and the **Scalable Matrix Extension (SME)** to teach modern SIMD patterns. They are two powerful, scalable vector extensions designed for modern workloads. Unlike NEON, these architecture extensions are not just wider; they are fundamentally different. They introduce predication, vector-length-agnostic (VLA) programming, gather/scatter, streaming modes, and tile-based compute with ZA state. The result is more power and flexibility, with a learning curve to match.
11+
This Learning Path uses the **Scalable Vector Extension (SVE)** and the **Scalable Matrix Extension (SME)** to demonstrate modern SIMD patterns. They are two powerful, scalable vector extensions designed for modern workloads. Unlike NEON, these architecture extensions are not just wider; they are fundamentally different. They introduce predication, vector-length-agnostic (VLA) programming, gather/scatter, streaming modes, and tile-based compute with ZA state. The result is more power and flexibility, but there can be a learning curve to match.
1212

13-
**SIMD Loops** offer a hands-on way to climb the learning curve. It is a public codebase of self-contained, real loop kernels written in C, Arm C Language Extensions (ACLE) intrinsics, and selected inline assembly. Kernels span tasks such as matrix multiply, sorting, and string processing. You can build them, run them, step through them, and adapt them for your own SIMD workloads.
13+
The **SIMD Loops** project offers a hands-on way to climb the learning curve. It is a public codebase of self-contained, real loop kernels written in C, Arm C Language Extensions (ACLE) intrinsics, and selected inline assembly. Kernels span tasks such as matrix multiply, sorting, and string processing. You can build them, run them, step through them, and adapt them for your own SIMD workloads.
1414

1515
> Repo: [SIMD Loops](https://gitlab.arm.com/architecture/simd-loops)
1616
17-
## What is SIMD Loops?
18-
19-
SIMD Loops is an open-source
20-
project, licensed under BSD 3-Clause, built to help you learn how to write SIMD code for modern Arm
21-
architectures, specifically using SVE and SME.
22-
It is designed for programmers who already know
23-
their way around NEON intrinsics but are now facing the more powerful and
24-
complex world of SVE and SME.
25-
26-
The goal of SIMD Loops is to provide working, readable examples that demonstrate
27-
how to use the full range of features available in SVE, SVE2, and SME2. Each
28-
example is a self-contained loop kernel, a small piece of code that performs
29-
a specific task like matrix multiplication, vector reduction, histogram, or
30-
memory copy. These examples show how that task can be implemented across different
31-
vector instruction sets.
32-
33-
Unlike a cookbook that tries to provide a recipe for every problem, SIMD Loops
34-
takes the opposite approach. It aims to showcase the architecture rather than
35-
the problem. The loop kernels are chosen to be realistic and meaningful, but the
36-
main goal is to demonstrate how specific features and instructions work in
37-
practice. If you are trying to understand scalability, predication,
38-
gather/scatter, streaming mode, ZA storage, compact instructions, or the
39-
mechanics of matrix tiles, this is where you will see them in action.
17+
SIMD Loops is an open-source project, licensed under BSD 3-Clause, built to help you learn how to write SIMD code for modern Arm architectures, specifically using SVE and SME. It is designed for programmers who already know their way around NEON intrinsics but are now facing the more powerful and complex world of SVE and SME.
18+
19+
The goal of SIMD Loops is to provide working, readable examples that demonstrate how to use the full range of features available in SVE, SVE2, and SME2. Each example is a self-contained loop kernel, a small piece of code that performs a specific task like matrix multiplication, vector reduction, histogram, or memory copy. These examples show how that task can be implemented across different vector instruction sets.
20+
21+
Unlike a cookbook that attempts to provide a recipe for every problem, SIMD Loops takes the opposite approach. It aims to showcase the architecture rather than the problem itself. The loop kernels are chosen to be realistic and meaningful, but the main goal is to demonstrate how specific features and instructions work in practice. If you are trying to understand scalability, predication, gather/scatter, streaming mode, ZA storage, compact instructions, or the mechanics of matrix tiles, this is where you can see them in action.
4022

4123
The project includes:
4224
- Many numbered loop kernels, each focused on a specific feature or pattern

content/learning-paths/cross-platform/simd-loops/2-using.md

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ git clone https://gitlab.arm.com/architecture/simd-loops simd-loops.git
1313
cd simd-loops.git
1414
```
1515

16-
Confirm you are using an Arm machine:
16+
Confirm that you are using an Arm machine:
1717

1818
```bash
1919
uname -m
@@ -33,11 +33,7 @@ arm64
3333

3434
## SIMD Loops structure
3535

36-
In the SIMD Loops project, the source code for the loops is organized under the `loops` directory. The complete
37-
list of loops is documented in the `loops.inc` file, which includes a brief
38-
description and the purpose of each loop. Every loop is associated with a
39-
uniquely named source file following the pattern `loop_<NNN>.c`, where
40-
`<NNN>` represents the loop number.
36+
In the SIMD Loops project, the source code for the loops is organized under the `loops` directory. The complete list of loops is documented in the `loops.inc` file, which includes a brief description and the purpose of each loop. Every loop is associated with a uniquely named source file following the pattern `loop_<NNN>.c`, where `<NNN>` represents the loop number.
4137

4238
A subset of the `loops.inc` file is below:
4339

@@ -84,27 +80,15 @@ void inner_loop_<NNN>(struct loop_<NNN>_data *data) { ... }
8480
// Main of loop: buffer allocation, loop function call, result checking
8581
```
8682

87-
Each loop is implemented in several SIMD extension variants. Conditional
88-
compilation selects one of the implementations for the
89-
`inner_loop_<NNN>` function.
83+
Each loop is implemented in several SIMD extension variants. Conditional compilation selects one of the implementations for the `inner_loop_<NNN>` function.
9084

91-
The native C implementation is written first, and
92-
it can be generated either when building natively with `-DHAVE_NATIVE` or through
93-
compiler auto-vectorization with `-DHAVE_AUTOVEC`.
85+
The native C implementation is written first, and it can be generated either when building natively with `-DHAVE_NATIVE` or through compiler auto-vectorization with `-DHAVE_AUTOVEC`.
9486

95-
When SIMD ACLE is supported (SME, SVE, or NEON),
96-
the code is compiled using high-level intrinsics. If ACLE
97-
support is not available, the build process falls back to handwritten inline
98-
assembly targeting one of the available SIMD extensions, such as SME2.1, SME2,
99-
SVE2.1, SVE2, and others.
87+
When SIMD ACLE is supported (SME, SVE, or NEON), the code is compiled using high-level intrinsics. If ACLE support is not available, the build process falls back to handwritten inline assembly targeting one of the available SIMD extensions, such as SME2.1, SME2, SVE2.1, SVE2, and others.
10088

101-
The overall code structure also includes setup and
102-
cleanup code in the main function, where memory buffers are allocated, the
103-
selected loop kernel is executed, and results are verified for correctness.
89+
The overall code structure also includes setup and cleanup code in the main function, where memory buffers are allocated, the selected loop kernel is executed, and results are verified for correctness.
10490

105-
At compile time, you can select which loop optimization to compile, whether it
106-
is based on SME or SVE intrinsics, or one of the available inline assembly
107-
variants.
91+
At compile time, you can select which loop optimization to compile, whether it is based on SME or SVE intrinsics, or one of the available inline assembly variants.
10892

10993
```console
11094
make

content/learning-paths/cross-platform/simd-loops/3-example.md

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ weight: 4
66
layout: learningpathall
77
---
88

9-
To illustrate the structure and design principles of SIMD Loops, consider loop 202 as an example
9+
To illustrate the structure and design principles of SIMD Loops, consider loop 202 as an example.
1010

11-
Use a text editor to open `loops/loop_202.c`
11+
Use a text editor to open `loops/loop_202.c`.
1212

1313
The function `inner_loop_202()` is defined around lines 60–70 in `loops/loop_202.c` and calls the `matmul_fp32` routine defined in `loops/matmul_fp32.c`
1414

15-
Open `loops/matmul_fp32.c` in your editor
15+
Open `loops/matmul_fp32.c` in your editor.
1616

1717
This loop implements single-precision floating-point matrix multiplication of the form:
1818

@@ -24,8 +24,7 @@ You can view matrix multiplication in two equivalent ways:
2424

2525
## Data structure
2626

27-
The loop begins by defining a data structure that captures the matrix
28-
dimensions (`M`, `K`, `N`) along with input and output buffers:
27+
The loop begins by defining a data structure that captures the matrix dimensions (`M`, `K`, `N`) along with input and output buffers:
2928

3029
```C
3130
struct loop_202_data {
@@ -43,19 +42,19 @@ For this loop:
4342
- Matrix `b` is stored in row-major order
4443
- The memory regions referenced by `a`, `b`, and `c` do not alias, as indicated by the `restrict` keyword
4544

46-
This layout helps optimize memory access patterns across the targeted SIMD architectures
45+
This layout helps optimize memory access patterns across the targeted SIMD architectures.
4746

4847
## Loop attributes
4948

5049
Loop attributes are specified per target architecture:
5150
- **SME targets**`inner_loop_202` is invoked with the `__arm_streaming` attribute and uses a shared `ZA` register context (`__arm_inout("za")`). These attributes are wrapped in the `LOOP_ATTR` macro
5251
- **SVE or NEON targets** — no additional attributes are required
5352

54-
This design enables portability across SIMD extensions
53+
This design enables portability across SIMD extensions.
5554

5655
## Function implementation
5756

58-
`loops/matmul_fp32.c` provides several optimizations of matrix multiplication, including ACLE intrinsics and hand-optimized assembly
57+
`loops/matmul_fp32.c` provides several optimizations of matrix multiplication, including ACLE intrinsics and hand-optimized assembly.
5958

6059
### Scalar code
6160

@@ -79,7 +78,7 @@ A scalar C implementation appears around lines 40–52. It follows the dot-produ
7978
8079
### SVE-optimized code
8180
82-
The SVE version uses indexed floating-point multiply–accumulate (`fmla`) to optimize the matrix multiplication operation. The outer product is decomposed into indexed multiply steps, and results accumulate directly in `Z` registers
81+
The SVE version uses indexed floating-point multiply–accumulate (`fmla`) to optimize the matrix multiplication operation. The outer product is decomposed into indexed multiply steps, and results accumulate directly in `Z` registers.
8382
8483
In the intrinsics version (lines 167–210), the innermost loop is structured as follows:
8584
@@ -130,23 +129,23 @@ In the intrinsics version (lines 167–210), the innermost loop is structured as
130129
}
131130
```
132131

133-
At the beginning of the loop, the accumulators (`Z` registers) are zeroed using `svdup` (or `dup` in assembly), encapsulated in the `ZERO_PAIR` macro
132+
At the beginning of the loop, the accumulators (`Z` registers) are zeroed using `svdup` (or `dup` in assembly), encapsulated in the `ZERO_PAIR` macro.
134133

135134
Within each iteration over the `K` dimension:
136-
- 128 bits (four consecutive floating-point values) are loaded from `A` using replicate loads `svld1rq` (or `ld1rqw`), via `LOADA_PAIR`
135+
- 128 bits (four consecutive floating-point values) are loaded from `A` using replicate loads `svld1rq` (or `ld1rqw`), through `LOADA_PAIR`
137136
- Two vectors are loaded from `B` using SVE vector loads, using `LOADB_PAIR`
138137
- Indexed `fmla` operations compute element–vector products and accumulate into 16 `Z` register accumulators
139138
- Partial sums build up the output tile
140139

141-
After all `K` iterations, results in the `Z` registers are stored to `C` using the `STORE_PAIR` macro
140+
After all `K` iterations, results in the `Z` registers are stored to `C` using the `STORE_PAIR` macro.
142141

143-
The equivalent SVE hand-optimized assembly appears around lines 478–598
142+
The equivalent SVE hand-optimized assembly appears around lines 478–598.
144143

145-
This loop shows how SVE registers and indexed `fmla` enable efficient decomposition of the outer-product formulation into parallel, vectorized accumulation
144+
This loop shows how SVE registers and indexed `fmla` enable efficient decomposition of the outer-product formulation into parallel, vectorized accumulation.
146145

147-
For SVE/SVE2 semantics and optimization guidance, see the [Scalable Vector Extensions resources](https://developer.arm.com/Architectures/Scalable%20Vector%20Extensions)
146+
For SVE/SVE2 semantics and optimization guidance, see the [Scalable Vector Extensions resources](https://developer.arm.com/Architectures/Scalable%20Vector%20Extensions).
148147

149-
### SME2-optimized code
148+
## SME2-optimized code
150149

151150
The SME2 implementation leverages the outer-product formulation of the matrix
152151
multiplication function, utilizing the `fmopa` SME instruction to perform the
@@ -226,17 +225,16 @@ For instruction semantics and SME/SME2 optimization guidance, see the [SME Progr
226225
227226
## Other optimizations
228227
229-
Beyond the SME2 and SVE implementations, this loop also includes additional
230-
optimized versions that leverage architecture-specific features
228+
Beyond the SME2 and SVE implementations, this loop also includes additional optimized versions that leverage architecture-specific features.
231229
232230
### NEON
233231
234-
The NEON version (lines 612–710) uses structure load/store combined with indexed `fmla` to vectorize the computation
232+
The NEON version (lines 612–710) uses structure load/store combined with indexed `fmla` to vectorize the computation.
235233
236234
### SVE2.1
237235
238-
The SVE2.1 version (lines 355–462) extends the base SVE approach using multi-vector loads and stores
236+
The SVE2.1 version (lines 355–462) extends the base SVE approach using multi-vector loads and stores.
239237
240238
### SME2.1
241239
242-
The SME2.1 version uses `movaz` / `svreadz_hor_za8_u8_vg4` to reinitialize `ZA` tile accumulators while moving data out to registers
240+
The SME2.1 version uses `movaz`/`svreadz_hor_za8_u8_vg4` to reinitialize `ZA` tile accumulators while moving data out to registers.

content/learning-paths/cross-platform/simd-loops/4-conclusion.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,4 @@ Whether you are moving from NEON or starting directly with SVE and SME, the proj
1515

1616
Use the repository to explore, modify, and benchmark kernels so you can understand tradeoffs and apply the patterns to your own workloads.
1717

18-
For more information and to get started, visit the GitLab project and see the [README.md](https://gitlab.arm.com/architecture/simd-loops/-/blob/main/README.md)
19-
for the latest instructions on building and running the code.
18+
For more information and to get started, visit the GitLab project and see the [README.md](https://gitlab.arm.com/architecture/simd-loops/-/blob/main/README.md) for the latest instructions on building and running the code.

0 commit comments

Comments
 (0)