C Mastery / Virtual Memory, Pages, Caches, and Hardware Memory
Part 4 — Memory Management

Virtual Memory, Pages, Caches, and Hardware Memory

This chapter connects C's memory model to the hardware and OS reality beneath it: virtual memory, pages, CPU caches, and the specialized memories of embedded systems (SRAM, flash, DMA).

Why This Matters

C programs think in terms of a flat address space, but that space is an illusion maintained by the MMU and OS. Caches determine performance; DMA and embedded memories determine correctness in low-level code. This is the bridge from language to machine.

Prerequisites

Core Concept

Virtual vs. physical memory

On hosted systems, your program sees virtual addresses, not physical ones. The OS and the MMU translate virtual pages to physical frames. This gives each process an isolated, contiguous address space and enables paging, swapping, and memory protection.

CPU caches

The CPU caches frequently used memory in a hierarchy (L1, L2, L3). Accessing cache-resident data is orders of magnitude faster than main memory. Caches operate on cache lines (typically 64 bytes), so locality matters (c.perf.cache-locality).

Embedded memory

Embedded systems have different memories with different properties:

MemoryProperties
Flashnon-volatile, read-mostly, stores code and constants
SRAMfast, volatile, stores variables and stack
EEPROMnon-volatile, byte-erasable, for small persistent data
MMIOmemory-mapped hardware registers (c.emb.mmio)

DMA and cache coherency

DMA (direct memory access) lets peripherals read/write memory without the CPU. DMA and CPU caches can disagree about memory contents, so DMA buffers need special handling: uncached regions, cache flushes/invalidations, or coherent memory. EMBEDDED

Examples

Observing page size (POSIX)

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    long pz = sysconf(_SC_PAGESIZE);
    printf("%ld\n", pz);
    return 0;
}

This is POSIX, not ISO C. Expected output is typically 4096.

Cache-friendly vs. cache-unfriendly access

/* stride-1 access is cache-friendly */
for (int i = 0; i < N; i++)
    sum += a[i];

/* strided access by a large factor is cache-unfriendly */
for (int i = 0; i < N; i += 64)
    sum += a[i];

The first loop touches every cache line once; the second touches one element per line, wasting bandwidth. Full treatment in c.perf.2.

How It Works

The MMU walks page tables (with TLB acceleration) to translate addresses and enforce permissions. The cache hierarchy sits between the CPU and memory, fetching whole cache lines on a miss. DMA controllers bypass the CPU and transfer directly to/from memory.

Variations

MPU (embedded)

Microcontrollers without an MMU often have an MPU (memory protection unit) that enforces regions/permissions but does not provide virtual memory.

Huge pages

Large pages (2 MiB, 1 GiB) reduce TLB pressure for large working sets. This is an OS-level optimization.

Common Mistakes

Undefined Behavior

page) is a hardware/OS fault, not ISO C UB — but the C-level cause (writing to a string literal) is UB.

Portability

Under the Hood

The MMU provides isolation and permission checking. The TLB caches translations. Caches exploit spatial and temporal locality. DMA requires cache coherency protocols or explicit maintenance.

Practical Usage

requires cache maintenance.

Exercises

1. Print the page size (POSIX sysconf) and the cache line size (via sysconf(_SC_LEVEL1_DCACHE_LINESIZE) where available). 2. Benchmark stride-1 vs. strided access to see cache effects. 3. Explain why DMA buffers may require cache flushes. 4. Describe the difference between flash and SRAM in embedded.

Deep Challenge

Design a cache-coherent DMA buffer scheme for an embedded system: explain when you need uncached memory vs. explicit cache invalidate/flush, and write the pseudocode for a DMA transfer with correct ordering. Discuss alignment and volatile.

References

platform/hardware concepts.

Verification

PLATFORM-SPECIFIC

verified.`

Progress

Concept checkboxes

Mastery levels

ConceptCurrent level (0–8)Target level
c.mem.virtual06
c.mem.page06
c.mem.cache06
c.mem.embedded-sram05
c.mem.dma05