Arrays & Buffers

Contiguous memory is the foundation of high-performance computing. In Mojo, you work with buffers that map directly to flat memory regions. Understanding strides, indexing, and memory layout (row-major vs column-major) is essential for writing code that doesn't fight the hardware.

Code

from std.memory import UnsafePointer

fn main():
  var ptr = alloc[Float64](10)
  for i in range(10):
    ptr[i] = Float64(i) * 2.0

  for i in range(10):
    print(ptr[i])

  ptr.free()

Row-Major vs Column-Major

A 2D matrix stored in flat memory. Row-major stores rows contiguously (C-style). Column-major stores columns contiguously (Fortran-style). Accessing along the wrong axis causes cache misses:

# Row-major: element [i][j] is at index i * cols + j
# Column-major: element [i][j] is at index j * rows + i

fn row_major_index(i: Int, j: Int, cols: Int) -> Int:
    return i * cols + j

Constraint

Allocate a flat buffer representing a 4×4 matrix. Fill it row-major. Then read it column-major and observe the access pattern difference. Print both traversal orders.

Why It Matters

A CPU cache line is 64 bytes (8 Float64 values). Sequential access loads the next 8 values for free. Strided access wastes the entire cache line. For a 1024×1024 matrix, wrong traversal order can be 10-100x slower.