Skip to content

Commit 24f3939

Browse files
updates
1 parent 4330f44 commit 24f3939

6 files changed

Lines changed: 61 additions & 31 deletions

File tree

content/learning-paths/servers-and-cloud-computing/bitmap_scan_sve2/01-introduction.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,18 @@ Bitmap scanning involves searching through a bit vector to find positions where
2323

2424
In database systems, bitmaps are commonly used to represent:
2525

26-
* **Bitmap Indexes**: each bit represents whether a row satisfies a particular condition
27-
* **Bloom Filters**: probabilistic data structures used to test set membership
28-
* **Column Filters**: bit vectors indicating which rows match certain predicates
26+
* **Bitmap indexes**: each bit represents whether a row satisfies a particular condition
27+
* **Bloom filters**: probabilistic data structures used to test set membership
28+
* **Column filters**: bit vectors indicating which rows match certain predicates
2929

3030
The operation of scanning a bitmap to find set bits is often in the critical path of query execution, making it a prime candidate for optimization.
3131

3232
## The evolution of vector processing for bitmap scanning
3333

3434
Here's how vector processing has evolved to improve bitmap scanning performance:
3535

36-
* **Generic Scalar Processing**: traditional bit-by-bit processing with conditional branches
37-
* **Optimized Scalar Processing**: byte-level skipping to avoid processing empty bytes
36+
* **Generic scalar processing**: traditional bit-by-bit processing with conditional branches
37+
* **Optimized scalar processing**: byte-level skipping to avoid processing empty bytes
3838
* **NEON**: fixed-width 128-bit SIMD processing with vector operations
3939
* **SVE**: scalable vector processing with predication and specialized instructions like MATCH
4040

@@ -61,6 +61,6 @@ Create a directory for your implementations:
6161
mkdir -p bitmap_scan
6262
cd bitmap_scan
6363
```
64-
## Next steps
6564

66-
In the next section, you’ll define the core bitmap data structure and utility functions for setting, clearing, and inspecting bits.
65+
## Next up: build the bitmap scanning foundation
66+
With your development environment set up, you're ready to dive into the core of bitmap scanning. In the next section, you’ll define a minimal bitmap data structure and implement utility functions to set, clear, and inspect individual bits.

content/learning-paths/servers-and-cloud-computing/bitmap_scan_sve2/02-bitmap-data-structure.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,6 @@ size_t bitvector_count_scalar(bitvector_t* bv) {
8383
}
8484
```
8585
86-
You now have a functional, compact bit vector in C for testing bitmap scanning performance. Next, you'll implement scalar, NEON, and SVE-based scanning routines that operate on this structure.
86+
## Next up: Implement and benchmark your first scalar bitmap scan
87+
88+
With your bit vector infrastructure in place, you're now ready to scan it for set bits—the core operation that underpins all bitmap-based filters in database systems.

content/learning-paths/servers-and-cloud-computing/bitmap_scan_sve2/03-scalar-implementations.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,14 @@ size_t result_count = 0;
7676
```
7777
Instead of iterating through each bit individually, this implementation processes one byte (8 bits) at a time. The main optimization over the previous scalar implementation is checking if an entire byte is zero and skipping it entirely. For sparse bitmaps, this can dramatically reduce the number of bit checks.
7878

79-
## Next steps
79+
## Next up: Accelerate bitmap scanning with NEON and SVE
8080

81-
Next, you’ll explore how to accelerate bitmap scanning using NEON and SVE SIMD instructions on Arm Neoverse platforms like Graviton4, comparing them directly to these scalar baselines.
81+
You’ve now implemented two scalar scanning routines:
8282

83+
* A generic per-bit loop for correctness and simplicity
84+
85+
* An optimized scalar version that improves performance using byte-level skipping
86+
87+
These provide a solid foundation and performance baseline—but scalar methods can only take you so far. To unlock real throughput gains, it’s time to leverage SIMD (Single Instruction, Multiple Data) execution.
88+
89+
In the next section, you’ll explore how to use Arm NEON and SVE vector instructions to accelerate bitmap scanning. These approaches will process multiple bytes at once and significantly outperform scalar loops—especially on modern Arm-based CPUs like AWS Graviton4.

content/learning-paths/servers-and-cloud-computing/bitmap_scan_sve2/04-vector-implementations.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,8 @@ size_t scan_bitvector_sve2_pnext(bitvector_t* bv, uint32_t* result_positions) {
152152
```
153153
The SVE implementation efficiently scans bitmaps by using `svcmpne_u8` to identify non-zero bytes and `svpnext_b8` to iterate through them sequentially. It extracts byte indices and values with `svlastb_u8`, then processes individual bits using scalar code. This hybrid vector-scalar approach maintains great performance across various bitmap densities. On Graviton4, SVE vectors are 128 bits (16 bytes), allowing processing of 16 bytes at once.
154154

155+
## Next up: Apply vectorized scanning to database workloads
156+
157+
With both NEON and SVE implementations in place, you’ve now unlocked the full power of Arm’s vector processing capabilities for bitmap scanning. These SIMD techniques allow you to process large bitvectors more efficiently—especially when filtering sparse datasets or skipping over large blocks of empty rows.
158+
159+
In the next section, you’ll learn how to apply these optimizations in the context of real database operations like bitmap index scans, Bloom filter probes, and column filtering. You’ll also explore best practices for selecting the right implementation based on bit density, and tuning for maximum performance on AWS Graviton4.

content/learning-paths/servers-and-cloud-computing/bitmap_scan_sve2/05-benchmarking-and-results.md

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -164,45 +164,58 @@ When running on a Graviton4 c8g.large instance with Ubuntu 24.04, the results sh
164164

165165
The optimized scalar implementation shows significant improvements over the generic scalar implementation due to:
166166

167-
1. **Byte-level Skipping**: Avoiding processing empty bytes
168-
2. **Reduced Function Calls**: Accessing bits directly rather than through function calls
169-
3. **Better Cache Utilization**: More sequential memory access patterns
167+
* **Byte-level Skipping**: Avoiding processing empty bytes
168+
* **Reduced Function Calls**: Accessing bits directly rather than through function calls
169+
* **Better Cache Utilization**: More sequential memory access patterns
170170

171171
## Optimized Scalar vs NEON
172172

173173
The NEON implementation shows further improvements over the optimized scalar implementation for sparse bit vectors due to:
174174

175-
1. **Chunk-level Skipping**: Quickly skipping 16 empty bytes at once
176-
2. **Vectorized Comparison**: Checking multiple bytes in parallel
177-
3. **Early Termination**: Quickly determining if a chunk contains any set bits
175+
* **Chunk-level Skipping**: Quickly skipping 16 empty bytes at once
176+
* **Vectorized Comparison**: Checking multiple bytes in parallel
177+
* **Early Termination**: Quickly determining if a chunk contains any set bits
178178

179179
## NEON vs SVE
180180

181181
The performance comparison between NEON and SVE depends on the bit density:
182182

183-
1. **Very Sparse Bit Vectors (0% - 0.01% density)**:
183+
* **Very Sparse Bit Vectors (0% - 0.01% density)**:
184184
- NEON performs better for empty bitvectors due to lower overhead
185185
- NEON achieves up to 127.41x speedup over generic scalar
186186
- SVE performs better for very sparse bitvectors (0.001% density)
187187
- SVE achieves up to 29.07x speedup over generic scalar at 0.001% density
188188

189-
2. **Higher Density Bit Vectors (0.1% - 10% density)**:
189+
* **Higher Density Bit Vectors (0.1% - 10% density)**:
190190
- SVE consistently outperforms NEON
191191
- SVE achieves up to 1.66x speedup over NEON at 0.01% density
192192

193193
## Key Optimizations in SVE Implementation
194194

195195
The SVE implementation includes several key optimizations:
196196

197-
1. **Efficient Non-Zero Byte Detection**: Using `svcmpne_u8` to quickly identify non-zero bytes in the bitvector.
197+
* **Efficient Non-Zero Byte Detection**: Using `svcmpne_u8` to quickly identify non-zero bytes in the bitvector.
198198

199-
2. **Byte-Level Processing**: Using `svpnext_b8` to efficiently find the next non-zero byte without processing zero bytes.
199+
* **Byte-Level Processing**: Using `svpnext_b8` to efficiently find the next non-zero byte without processing zero bytes.
200200

201-
3. **Value Extraction**: Using `svlastb_u8` to extract both the index and value of non-zero bytes.
201+
* **Value Extraction**: Using `svlastb_u8` to extract both the index and value of non-zero bytes.
202202

203-
4. **Hybrid Vector-Scalar Approach**: Combining vector operations for finding non-zero bytes with scalar operations for processing individual bits.
203+
* **Hybrid Vector-Scalar Approach**: Combining vector operations for finding non-zero bytes with scalar operations for processing individual bits.
204204

205-
5. **Prefetching**: Using `__builtin_prefetch` to reduce memory latency by prefetching the next chunk of data.
205+
* **Prefetching**: Using `__builtin_prefetch` to reduce memory latency by prefetching the next chunk of data.
206206

207+
## Next up: Apply what you’ve learned to real-world workloads
208+
209+
Now that you’ve benchmarked all four bitmap scanning implementations—scalar (generic and optimized), NEON, and SVE—you have a data-driven understanding of how vectorization impacts performance across different bitmap densities.
210+
211+
In the next section, you’ll explore how to apply these techniques in real-world database workloads, including:
212+
213+
* Bitmap index scans
214+
215+
* Bloom filter checks
216+
217+
* Column-level filtering in analytical queries
218+
219+
You’ll also learn practical guidelines for choosing the right implementation based on bit density, and discover optimization tips that go beyond the code to help you get the most out of Arm-based systems like Graviton4.
207220

208221

content/learning-paths/servers-and-cloud-computing/bitmap_scan_sve2/06-application-and-best-practices.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,26 @@ Columnar databases frequently use bitmap filters to track which rows satisfy fil
2525

2626
Based on the benchmark results, here are some best practices for optimizing bitmap scanning operations:
2727

28-
1. **Choose the right implementation based on the expected bit density**:
28+
* Choose the right implementation based on the expected bit density**:
2929
- For empty bit vectors: NEON is optimal
3030
- For very sparse bit vectors (0.001% - 0.1% set bits): SVE is optimal due to efficient skipping
3131
- For medium to high densities (> 0.1% density): SVE still outperforms NEON
3232

33-
2. **Implement Early Termination**: Always include a fast path for the no-hits case, as this can provide dramatic performance improvements.
33+
* Implement Early Termination**: Always include a fast path for the no-hits case, as this can provide dramatic performance improvements.
3434

35-
3. **Use Byte-level Skipping**: Even in scalar implementations, skipping empty bytes can provide significant performance improvements.
35+
* Use Byte-level Skipping**: Even in scalar implementations, skipping empty bytes can provide significant performance improvements.
3636

37-
4. **Consider Memory Access Patterns**: Optimize memory access patterns to improve cache utilization.
37+
* Consider Memory Access Patterns**: Optimize memory access patterns to improve cache utilization.
3838

39-
5. **Leverage Vector Instructions**: Use NEON or SVE/SVE2 instructions to process multiple bytes in parallel.
39+
* Leverage Vector Instructions**: Use NEON or SVE/SVE2 instructions to process multiple bytes in parallel.
4040

4141
## Conclusion
4242

43-
The SVE instructions provides a powerful way to accelerate bitmap scanning operations in database systems. By implementing these optimizations on Graviton4 instances, you can achieve significant performance improvements for your database workloads.
43+
Scalable Vector Extension (SVE) instructions provide a powerful and portable way to accelerate bitmap scanning in modern database systems. When implemented on Arm Neoverse V2–based servers like AWS Graviton4, they deliver substantial performance improvements across a wide range of bit densities.
44+
45+
The SVE implementation shows particularly impressive performance for sparse bitvectors (0.001% - 0.1% density), where it outperforms both scalar and NEON implementations. For higher densities, it maintains a performance advantage by amortizing scan costs across wider vectors.
46+
47+
These performance improvements can translate directly to faster query execution times, especially for analytical workloads that involve multiple bitmap operations.
48+
4449

45-
The SVE implementation shows particularly impressive performance for sparse bitvectors (0.001% - 0.1% density), where it outperforms both scalar and NEON implementations. For higher densities, it continues to provide substantial speedups over traditional approaches.
4650

47-
These performance improvements can translate directly to faster query execution times, especially for analytical workloads that involve multiple bitmap operations.

0 commit comments

Comments
 (0)