cache write policies (write-back versus write-through)
Reading from a cache is easy to picture, but what should happen when the CPU WRITES? You have changed a value that lives both in the cache and (in stale form) in DRAM. Two questions arise: when do you push the change down to memory, and what do you do if the address you are writing was not even cached yet? The cache write policy is the set of answers, and it is mostly fixed by the hardware, not chosen by you — but knowing it explains real performance behavior.
On the WHEN question: a write-through cache sends every write to the next level immediately, keeping memory always current but generating heavy write traffic. A write-back cache (what nearly all modern L1/L2/L3 caches use) instead updates only the cache line and marks it dirty; the line is written down to memory lazily, only when it is evicted. This collapses many writes to the same line into a single eventual memory write, which is why write-back is the default for performance. On the second question — a write to an address not currently cached — a write-allocate policy first loads the line into cache (so the write, and likely-nearby future writes, become fast cache writes), while a no-write-allocate policy writes straight past to memory without caching. The common pairing is write-back with write-allocate.
Where this surfaces in practice: because write-back caches hold dirty data, the contents of DRAM can lag what the CPU has actually computed until eviction — which is exactly why memory-mapped device registers and DMA buffers must be handled carefully (often marked uncacheable or flushed explicitly). It also explains why writing a fresh, never-read buffer can be wasteful under write-allocate: the hardware loads the old contents of each line just to overwrite them, which is why bulk-store and non-temporal store instructions exist to bypass the cache when you know you are not going to read the data back soon.
Zeroing a huge buffer you will then DMA out: under write-back + write-allocate, each store first fetches the old line. Using non-temporal stores (e.g. the _mm_stream_si128 intrinsic) writes straight to memory and skips that pointless read-for-ownership.
Write-allocate helpfully caches data you will reuse — but wastefully fetches lines you only mean to overwrite.
You rarely choose the policy in normal code; it matters mainly for device drivers, DMA, and high-throughput streaming writes. Do not reach for non-temporal stores routinely — they bypass the cache, so they hurt if you DO read the data back soon.