이 표독스러운 그림은 기말고사에서도 계속된다! 😭


파이프라인이 왜 빠른가?

동시에 같은 하드웨어 자원을 사용하려고 할 때 발생
필요한 자원이 사용 중(busy)하면 발생하는 충돌

이전 명령어의 결과값을 다음 명령어가 필요로 하는데, 그 결과가 아직 준비되지 않은 경우 발생 -> 이전 명령어가 데이터 읽기/쓰기를 완료할 때까지 기다려야 함
add $s0, $t0, $t1 # $s0 = $t0 + $t1
sub $t2, $s0, $t3 # $s0 를 즉시 사용해야 함
1. 이전 명령어의 완료되지 않은 결과에 현재 명령어가 의존한다
Data Hazard가 발생하면, 파이프라인은 필요한 데이터가 준비될 때까지 대기해야 하며, 그 후에야 의존하는 명령어가 진행될 수 있다.
2. 결과가 계산되는 즉시 사용한다
Forwarding은 결과가 레지스터에 저장될 때까지 기다리지 않고, 계산되자마자 즉시 사용할 수 있게 해준다.
3. 이전 명령어가 메모리에서 읽어온 데이터에 현재 명령어가 의존할 때 발생한다.
메모리 접근에는 시간이 걸리기 떄문에, 읽어온 데이터는 바로 다음 명령어가 즉시 사용할 수 있는 상태가 아니다.
이 해저드는, 의존하는 명령어가 데이터를 필요로 하는 시점에서 데이터 자체가 아직 준비되지 않았기 때문에, Forwarding만으로는 해결할 수 없다.
load-use hazard에서는 필요한 데이터가 load 명령어의 메모리 접근 단계가 끝날 때까지 준비되지 않는다.

load 다음에 바로 dependent instruction을 두지 않았기 때문
제어 동작은 이전 명령어의 결과에 의존하기 때문에 발생
branch 명령어는 프로그램 흐름을 결정한다
1. 다음 명령어를 가져올지 말지는 branch가 성공했는지 실패했는지에 따라 결정됨
-> branch가 "참"이면 다른 주소로 점프하고, "거짓"이면 다음 연속 명령어 실행
2. 파이프라인은 분기 결과를 미리 알 수 없음 -> 잘못된 명렁어를 가져오면 제어 해저드 발생
다음 명령어를 가져오기 전에, branch 결과가 결정될 때까지 기다려야 함

더 긴 파이프라인에서는 분기 결과를 초기에 쉽게 결정할 수 없음
stall(지연)로 인한 성능 손실이 매우 커지기 때문에 용납할 수 없게 됨
branch의 결과를 예측
예측이 틀렸을 때만 stall이 발생
branch가 발생하지 않는다고(default) 예측할 수 있음
지연 없이 branch 명령어 다음 명령어를 가져올 수 있음

일반적인 branch 패턴에 기반하여 예측
예: 반복문(loop)이나 if 문과 같은 분기에서
하드웨어가 실제 branch 동작을 측정 (하드웨어가 실제 branch 동작을 측정)
향후 branch 동작도 과거 패턴을 계속 따를 것이라고 가정
예측이 틀리면, 다시 올바른 명령어를 fetch하는 동안 stall이 발생하며
그 뒤 branch history를 업데이트

pipeline registers: 파이프라인은 한 사이클마다 다음 단계로 데이터를 넘기는데 이전 사이클에서 만들어진 값을 저장해 두기 위해 이 데이터를 잠깐 “붙잡아” 두는 저장 공간
MIPS 파이프라인에서 단계 사이에 있는 파란색 레지스터들은 각 사이클마다 생성된 결과를 저장하고 다음 단계로 전달하기 위한 필수 요소임
IF/ID 레지스터
IF 단계에서 읽은 instruction(명령어)
PC+4 등을 ID 단계로 전달하기 위해 저장함
ID/EX 레지스터
register file에서 읽은 값(read data1, data2)
sign-extend된 immediate
컨트롤 신호들
→ EX 단계로 넘기기 전에 잠시 보관
EX/MEM 레지스터
ALU 결과(계산된 주소 또는 연산 결과)
branch 결과 정보
memory에 저장할 데이터(write data)
→ MEM 단계로 전달하기 위해 저장됨
MEM/WB 레지스터
메모리에서 읽은 값(read data)
ALU 결과
→ WB 단계에서 레지스터에 쓸 값을 저장

여러 명령어가 동시에 다른 단계에서 실행될 수 있음
각 lw 명령어는 5단계(IF–ID–EX–MEM–WB)를 거침