5 things you never knew your CPU did for you

Matt Godbolt / @mattgodbolt

Your (Intel) CPU

1. Guesses how your data is accessed

test:
    lea rdx, [rdi+4+rax*4] ; rdx points at the end
    xor eax, eax           ; accum = 0
.loop
    add eax, [rdi]         ; add next value
    add rdi, 4             ; move pointer along
    cmp rdi, rdx           ; reached end?
    jne loop               ; no, keep going
    ret                    ; yay we're done

2. Turns CISC into RISC

mov eax, 1      ; eax = 1

add [rdi+16], 1 ; tmp = rdi + 16
                ; tmp2 = read(tmp)
                ; tmp2++
                ; write(tmp, tmp2)

3. Reschedules your code

mov eax, [rdi]  ; eax = *rdi
add eax, ebx    ; eax += ebx
mov [rdi], eax  ; *rdi = eax

mov edx, [rsi]  ; edx = *rsi
add edx, ebx    ; edx += ebx
mov [rsi], edx  ; *rsi = edx

4. Converts to SSA form

mov eax, [rdi]  ; eax = *rdi
add eax, ebx    ; eax += ebx
mov [rdi], eax  ; *rdi = eax

mov eax, [rsi]  ; eax = *rsi
add eax, ebx    ; eax += ebx
mov [rsi], eax  ; *rsi = eax

4. Converts to SSA form

mov eax, [rdi]  ; eax0 = *rdi
add eax, ebx    ; eax1 = eax0 + ebx
mov [rdi], eax  ; *rdi = eax1

mov eax, [rsi]  ; eax2 = *rsi
add eax, ebx    ; eax3 = eax2 + ebx
mov [rsi], eax  ; *rsi = eax3

5. Predicts the future

.loop
    add eax, [rdi]         ; add next value
    add rdi, 4             ; move pointer along
    cmp rdi, rdx           ; reached end?
    jne loop               ; no, keep going

5. Predicts the future

    add eax, [rdi]  ; eax1 = eax0 + *rdi0
    add rdi, 4      ; rdi1 = rdi0 + 4
    cmp rdi, rdx    ; cmp rdi1, rdx
    jne loop        ; predicted taken
    add eax, [rdi]  ; eax2 = eax1 + *rdi1
    add rdi, 4      ; rdi2 = rdi1 + 4
    cmp rdi, rdx    ; cmp rdi2, rdx
    jne loop        ; predicted not taken
    ret

Summary

  1. Prefetches data
  2. Converts to µcode
  3. OoO execution
  4. Register renaming
  5. Branch prediction

Any questions