liveBook · Manning

Instruction hazard

As explained in 100 Go Mistakes and How to Avoid Them

An instruction hazard is a condition that prevents or restricts the parallel execution of processor instructions.

An instruction hazard restricts parallel execution when instructions branch on an uncertain condition or depend on one another’s results. Instruction-level parallelism can reduce total time, but hazards limit that benefit. section 12.3

Diagnose the hazard before changing the code:

  • A control hazard occurs when a conditional instruction and a following instruction cannot safely run together. Branch prediction may speculate, but a wrong prediction flushes the pipeline and costs roughly 10–20 clock cycles. section 12.3
  • A data hazard occurs when one instruction needs a value produced by another; forwarding can reduce the impact but cannot remove the dependency. section 12.3

Separating a dependent check

In `s[0]++; if s[0]%2 == 0 { s[1]++ }`, the check depends on the increment. A rewritten loop stores the old value in `v`, increments `s[0]`, and checks `v`; the two increment steps can then execute in parallel when the dependency is removed. section 12.3

func add(s [2]int64) [2]int64 {     #1
    for i := 0; i < n; i++ {
        s[0]++
        if s[0]%2 == 0 {
            s[1]++
        }
    }
    return s
}
 
func add2(s [2]int64) [2]int64 {    #2
    for i := 0; i < n; i++ {
        v := s[0]                   #3
        s[0] = v + 1
        if v%2 != 0 {
            s[1]++
        }
    }
    return s
}

Compare the dependent `add` implementation with `add2`, which exposes the value before incrementing and changes the dependency pattern. section 12.3

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Explains control and data hazards, branch prediction, pipeline flushing, and forwarding, but stops short of hardware implementation details.
Examples
Uses register dependencies and two Go increment-loop implementations to expose and reduce a data hazard.
What it assumes
Assumes familiarity with processor instructions, registers, conditionals, and basic Go increment and loop syntax.
What you can do after
Diagnose dependencies in low-level execution and restructure suitable code to expose more parallelism.
How it connects
Links instruction-level parallelism with control hazard, data hazard, branch prediction, forwarding, and pipeline execution.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.