CodeBlanks Logo Icon CodeBlanks

Vectorization

Learn automatic parallelization with SIMD vectorization.

Vectorization

Vectorization is the compiler turning a loop into SIMD (Single Instruction Multiple Data) instructions. A single instruction processes multiple array elements; this gives a speedup.

On modern CPUs SSE/AVX registers process 4-16 ints at once. The compiler auto-vectorizes with -O3. Obstacles: pointer aliasing (two pointers may point to the same memory), conditions inside the loop, complex dependencies. The __restrict__ keyword says there is no aliasing.

Helping vectorization

For the compiler to vectorize a loop: the loop must be simple (single block, no condition), the trip count must be known in advance (constant or n), and pointers must be disjoint (no aliasing). Writing int* __restrict__ a declares no aliasing.

Example: void add(int* __restrict__ a, int* b, int n) { for (int i = 0; i < n; ++i) a[i] += b[i]; }. Here a and b are disjoint, so the compiler can safely process each step with SIMD. Without vectorization each step is processed one by one; that is slower.

Practice Write a vectorizable sum

Write int sum(int* a, int n). Body: int s = 0; for (int i = 0; i < n; ++i) s += a[i]; return s;. In main define int a[4] = {1, 2, 3, 4}; and write std::cout << sum(a, 4);.

Starter code

main.cpp
#include <iostream>

// Define the sum function here

int main() {
    // Define the a array, call sum and print it
    return 0;
}

Sample solution

main.cpp
#include <iostream>

int sum(int* a, int n) {
    int s = 0;
    for (int i = 0; i < n; ++i) s += a[i];
    return s;
}

int main() {
    int a[4] = {1, 2, 3, 4};
    std::cout << sum(a, 4);
    return 0;
}

Expected output

10

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Match each piece to its role

Term Meaning
SIMD Single instruction multiple data
#pragma omp simd OpenMP vectorization
__restrict__ Pointer disjointness
-O3 Vectorization flag

2 Complete the restrict keyword

Question
void add(int* ________ a, int* b, int n) { for (int i = 0; i < n; ++i) a[i] += b[i]; }
Answer
void add(int* __restrict__ a, int* b, int n) { for (int i = 0; i < n; ++i) a[i] += b[i]; }

Explanation: __restrict__ says there is no aliasing.

3 What optimization does -O3 enable?

main.cpp
g++ -O3 main.cpp
  • Nothing
  • Only warnings
  • Aggressive vectorization and loop unrolling Correct answer
  • The same thing

Explanation: -O3 adds aggressive vectorization and loop unrolling on top of -O2.

All lessons in Expert