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
