0Pricing
Assembly Language & x86 Low-Level Systems Programming · Lesson

Branch Prediction and Speculative Execution

See how modern CPUs predict branches and execute speculatively to hide latency, how mispredictions cost cycles, and how side effects led to Spectre-class attacks.

Branch Prediction and Speculative Execution is a free Assembly Language & x86 Low-Level Systems Programming lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Assembly Language & x86 Low-Level Systems Programming learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

The Pipeline Problem

Modern CPUs are deeply pipelined, fetching and decoding many instructions ahead. But a conditional branch is a fork: the CPU does not yet know which path to fetch. Stalling would waste the whole pipeline.

Branch Prediction

To avoid stalls the CPU predicts which way a branch will go and keeps fetching. If correct, no time is lost. If wrong, the pipeline is flushed — a costly misprediction penalty of 15-20+ cycles.

How Predictors Learn

The Branch Target Buffer and history tables record past outcomes. A simple 2-bit saturating counter remembers whether a branch was recently taken, predicting that loops keep looping.

Speculative Execution

Beyond predicting, the CPU speculatively executes the predicted path before the condition resolves. If the guess holds, results are committed; if not, they are discarded as if they never ran — architecturally.

Writing Predictable Branches

You help the predictor by making branches consistent. A branch that is almost always taken predicts well; a random branch defeats prediction. Sorting data before a conditional loop can dramatically speed it up.

for (int i = 0; i < n; i++)
    if (data[i] >= 128)   // predictable only if data is sorted
        sum += data[i];

A Runnable Benchmark

This C program shows the dramatic effect of sorted vs unsorted data on a branch-heavy loop. Run it and compare timings.

#include <stdio.h>
#include <stdlib.h>
int main(void) {
    int n = 32768;
    int *d = malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) d[i] = rand() % 256;
    long sum = 0;
    for (int r = 0; r < 1000; r++)
        for (int i = 0; i < n; i++)
            if (d[i] >= 128) sum += d[i];
    printf("sum=%ld\n", sum);
    free(d);
    return 0;
}

Branchless Programming

You can sometimes eliminate a branch entirely with arithmetic or conditional-move instructions (cmov), so the CPU never needs to predict.

cmp eax, 128
cmovge ebx, ecx   ; conditionally move, no branch to mispredict

Likely/Unlikely Hints

Compilers expose hints like __builtin_expect (the source of likely()/unlikely() macros) so hot paths fall through and cold paths jump away, improving instruction-cache layout.

if (__builtin_expect(error, 0)) {
    handle_error();   // marked cold/unlikely
}

The Security Side Effect

Speculative results are discarded architecturally — but they leave traces in the cache. Speculatively loaded data warms cache lines, and that timing difference can be measured. This is the basis of side-channel leaks.

Spectre in a Nutshell

Spectre tricks the predictor into speculatively reading memory it should not, then leaks the value through a cache timing side channel. The reads never commit, so they bypass normal bounds checks during the speculation window.

Mitigations

Defenses include serializing instructions (lfence) to stop speculation past a bounds check, retpolines for indirect branches, and microcode updates. They trade some performance for safety.

cmp index, limit
jae out_of_range
lfence            ; block speculation past the check

Quick Check

Test your understanding of speculation.

Recap

You learned how CPUs hide branch latency:

  • Branch prediction guesses the path; mispredicts cost a pipeline flush
  • Speculative execution runs the predicted path early
  • Predictable branches, cmov, and likely/unlikely hints boost speed
  • Speculation leaves cache side effects exploited by Spectre; lfence and retpolines mitigate it

Frequently asked questions

Is the “Branch Prediction and Speculative Execution” lesson free?

Yes — the full text of “Branch Prediction and Speculative Execution” is free to read here on the web, and the Assembly Language & x86 Low-Level Systems Programming course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Assembly Language & x86 Low-Level Systems Programming course, upgrade to CoddyKit PRO.

What will I learn in “Branch Prediction and Speculative Execution”?

See how modern CPUs predict branches and execute speculatively to hide latency, how mispredictions cost cycles, and how side effects led to Spectre-class attacks. You practise Assembly Language & x86 Low-Level Systems Programming with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Assembly Language & x86 Low-Level Systems Programming?

No prior experience is required. Assembly Language & x86 Low-Level Systems Programming on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Branch Prediction and Speculative Execution” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Assembly Language & x86 Low-Level Systems Programming lesson?

Yes. Every Assembly Language & x86 Low-Level Systems Programming lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Cache Coherency and Performance
  2. Hand-Optimizing Critical Sections
  3. Buffer Overflows and Shellcode
  4. Branch Prediction and Speculative Execution
← Back to Assembly Language & x86 Low-Level Systems Programming