⚡ Zig Guide LiveUnofficial
✓ Zig 0.17.0-dev.1454+5faa79730On an older Zig?

Vectors

const std = @import("std");
const expect = std.testing.expect;

test "element-wise arithmetic" {
    const a: @Vector(4, i32) = .{ 1, 2, 3, 4 };
    const b: @Vector(4, i32) = .{ 10, 20, 30, 40 };
    const sum = a + b; // one operation across all lanes
    try expect(sum[0] == 11);
    try expect(sum[3] == 44);
}

test "reduce across lanes" {
    const v: @Vector(4, i32) = .{ 1, 2, 3, 4 };
    try expect(@reduce(.Add, v) == 10);
    try expect(@reduce(.Max, v) == 4);
}

test "splat fills every lane" {
    const v: @Vector(4, i32) = @splat(7);
    try expect(@reduce(.Add, v) == 28);
}

test "comparisons produce a vector of bools" {
    const a: @Vector(4, i32) = .{ 1, 5, 3, 7 };
    const b: @Vector(4, i32) = .{ 4, 4, 4, 4 };
    const mask = a > b; // @Vector(4, bool)
    try expect(@reduce(.Or, mask));
    try expect(!@reduce(.And, mask));

    // Select lane-wise between two vectors.
    const picked = @select(i32, mask, a, b);
    try expect(picked[0] == 4 and picked[1] == 5);
}

test "vectors and arrays convert" {
    const arr = [_]i32{ 1, 2, 3, 4 };
    const v: @Vector(4, i32) = arr;
    const back: [4]i32 = v;
    try expect(back[2] == 3);
}

@Vector(N, T) is a SIMD vector of N lanes. Arithmetic operators work element-wise across all lanes at once, compiling to real vector instructions where the target has them:

const sum = a + b;   // one operation, four lanes

The supporting builtins

BuiltinDoes
@splat(x)fill every lane with x
@reduce(.Add, v)collapse lanes to one value
@select(T, mask, a, b)pick lane-wise between two vectors
@shufflerearrange lanes

Comparisons produce a @Vector(N, bool) mask rather than a single bool, which is why @reduce(.Or, mask) or @select is how you act on the result.

Vectors and arrays interconvert

const v: @Vector(4, i32) = arr;   // array -> vector
const back: [4]i32 = v;           // vector -> array

Same data, different type. Keep values in vector form through a computation and convert at the edges.

When to bother

Zig will often auto-vectorise a plain loop. Explicit vectors are for when you need the guarantee, or when the operation does not map onto a simple loop. If the target lacks SIMD, the code still works. The compiler lowers it to scalar operations.

Two cookbook recipes put these builtins to work: a SIMD dot product for arithmetic and SIMD byte scanning for searching.