Pipelining 자체는 뭔지 안다고 가정하자.

Performance & Cost Model

pipelining 사이사이에 delay T가 있을 때 throughput = 1/(T+S) where S=latch delay

k단계로 pipeline했다고 생각해보자.

Throughput = 1 / (T/k+S)

Cost = G + L*k (G: combinational logic 전체의 cost, L: gate의 개수)

따라서 Cost-performance tradeoff라는 것이 존재한다. 미분해서 C/P의 최소값을 구해보면

k_opt = \sqrt(GT/LS) 이렇게 됨

Pipelining with Pipeline registers installed

이렇게 각 단계 사이에 register를 설치해준다.

진행되는 방식은 slide 보면 나오니까 생략

Control for pipelining

Pipelining을 하면 Control signal 또한 pipeline되어 있어야 한다. (정확한 타이밍에 0/1값이 정해져 있어야 하기 때문에)

2가지 방법이 있는데

  1. single-cycle이랑 똑같이 Instruction decode단계에서 decode하고 control signal들을 buffer한다.
  2. Instruction field (opcode, funct3, funct7) 등을 pipeline에다가 집어넣고 EX, MEM, WB 등을 통해 decode 해 준다.

사진 속 방법이 1번과 같은 방법이다.

그러나 현실적으로 pipelining에는 여러 가지 문제가 있는데…

Data hazards in pipelining

8단원

  • True Dependency (RAW - Read After Write)
  • Anti Dependency (WAR - Write After Read)
  • Output Dependency (WAW - Write After Write)

뒤에서 Hazard의 종류는 더 정리해서 보도록 하자

Pipeline stall

PCWrite 랑 IF/ID.Write 를 disable시켜서 PC가 새로운 instruction을 fetch하도록 한다.

RegWriteID 와 MemWriteID도 disable시킨다

Impact of stall on performance

Average IPC with stall: N/(N+S) when there are N instructions and S stall cycles

Data forwarding

Computational result를 가져와서 data를 forwarding하는 것

lw instruction 같은 경우, 실제로 data를 produce하는 건 memory에서 read할 때기 때문에 forwarding을 사용해도 stall이 하나 필요함. 이걸 load-use hazard라고 한다

Copy
lw x2 20(x1)
and x4 x2 x5

이거 빼면 웬만한 data hazard는 forwarding으로 stall 없이 해결할 수 있다.

Code scheduling

컴파일러가 자체적으로 코드 순서를 바꿔서 lw 직후에 그 값을 사용하지 않도록 하는 것

Superpipelining

각 단계를 더 짧게 만들어서 clock cycle을 줄이고 throughput을 올리고자 하는 접근.

그런데 문제는

  • pipeline hazard의 개수를 늘린다 (stage 자체가 여러 개가 되니까)
  • data forwarding과 hazard detection을 더 복잡하게 만든다

Control hazard

9단원

일단 대부분의 경우 branch를 하니까, 할거라고 일단 예측을 한다.

안 할 경우 pipeline을 flush 해버린다 (NOPs, PC assumption)

ALU execution이 되고 나서야 branch가 taken인지, not taken인지 알 수 있다.

IPC: branch prediction을 얼마나 잘했는지 판단하는 지표로 사용된다.

IPC = 1 / (1 + branch prediction을 잘못할 확률 * 잘못된 guess에 대한 penalty)

1. 일반적인 경우

recall) IF → ID → EX → MEM → WB

beq x1 x0 16 에서 PC+16 값이 PC로 WB 될 때까지 3개의 bubble이 필요하기 때문에

그림과 같이 3개의 cycle이 낭비된다.

2. EX stage에서 비교연산과 동시에 계산해버린다

branch의 경우를 생각해 보자.

  • PC use는 IF 단계에서, PC produce (next PC) 는 EX stage에서 비교연산을 함과 동시에 produce된다.
  • 원래는 MEM 단계까지 기다려야 했었는데, EX 단계에서 branch condition 및 branch target address를 계산한다.
  • 20%가 branch instruction이고 70%가 branch taken일 때,

이렇게 훨씬 향상된 성과를 보여준다!

ID stage에 comparator를 만들어서 branch를 미리 해결하면, 잘못 take한 branch에 대한 페널티를 1 cycle까지 줄일 수 있음.

3. ID stage에서 해결한다

  • beq와 같이 register 값만 알아도 branch 여부를 알 수 있는 instruction의 경우 ID stage에서 해결하는 것도 가능하다. 즉, PC use: IF / PC produce: ID
  • ID stage에서 comparator를 추가하여 branch condition인지 아닌지를 판별한다.

그림을 보면

  • x1, x2를 register read한 후에 ID 단계에서 comparator가 작동해서, 같으면 branch taken.
  • Compute target address: immgen block에서 offset을 바로 generate하고, offset<<1을 current PC에 더해서 target PC를 계산한다.
  • 만약에 prediction이 잘못되면, flush해버린다

Hazard detection unit

branch instruction이 writeback이 아직 되지 않은 value에 depend하는지 확인한다. 예를들어

Copy
add x1 x2 x3
beq x1 x0 label

(잘 보면 data forwarding unit도 있음)

요약: Hazard의 종류

Data hazard (8단원)

  • 아직 read/write 되지 않은 data를 읽으려고 할 때 발생
  • Data dependency (RAW), Anti dependency(WAR), Output dependency(WAW) 등
  1. Control hazard (9단원)
  2. Structural hazard (7단원)



'cs > csed311' 카테고리의 다른 글

11. Exceptions and Interrupt  (0) 2025.04.14
10. Pipelined CPU - Branch Prediction  (0) 2025.04.14
5-6 Single/Multi cycle CPU  (0) 2025.04.14
4. Performance  (0) 2025.04.14
2-4 ISA (instruction set architecture)  (0) 2025.04.14