컴퓨터 구조

mips pipeline hazard (컴퓨터구조 2022-2학기)

땅콩콩 2022. 11. 26. 14:23
pipeline hazard

 

파이프라인 프로세서에서 명령어의 수행이 끝나기 전에 다른 명령어의 수행이 시작되기 때문에 생기는 문제!

기본적으로 pipeline stall을 하는 방법으로 해결할 수 있지만 (새 instruction을 fetch하지 않고 한 싸이클 쉬는것) stall이 많을수록 프로세서의 performance는 떨어지게 됨. 따라서 다양한 해결방법을 통해 stall을 최소화해야 한다.

 

1. Structural hazard

  • pipeline에서 한 사이클동안 여러개의 instruction이 수행되어서 생기는 구조적 문제!
  • 서로 다른 instruction이 같은 리소스를 사용할때 conflict가 발생한다.
 instruction memory와 data memory를 하드웨어상에서 분리해서 해결할 수 있음.
(이렇게 안하고 메모리는 하나로 두고 instruction cache와 memory cache를 분리하는 방법도 있음)

 

 

2. Data hazard

  • 하나의 instruction이 끝나기도 전에 다음 instruction이 시작되기 때문에 생기는 문제
  • 이 data hazard는 data dependency때문에 발생하는데, 값이 변환되어 레지스터에 써지기도 전에 그 레지스터에서 값을 읽어오려고 하기 때문에 문제가 발생하는 것이다.
  • 그러나 data dependency가 있더라도 register에서 값을 읽어오는 시점이 이전 instruction에 의해 새 register값이 써진 이후라면 hazard가 발생하지 않는다. (모든 data dependency가 hazard가 되는것은 아님.)
  • forwarding(bypassing)을 통해 해결할 수 있다. (그러나 어쩔수없이 stall이 필요한 경우도 있음)
forwarding이란? 
레지스터에 값이 써지기 전에 ALU연산이 끝나면, 혹은 메모리를 읽고나면 그 결과가 pipeline register에는 써지기 때문에 그 값을 이후에 실행하는 instruction의 operand로 가져와서 연산하는 방법!
단, forwarding은 같은 cycle안에서 이루어져야 하고, 이전 cycle의 값을 forwarding할수는 없다.
또한 회로상에서는 mux를 추가해서 forwarding을 할지말지 선택하는 부분을 추가해야 한다.
forwarding을 할지 말지, 한다면 어느 pipeline register에서 할지를 forwarding unit에서 결정하는 근거는? 
앞 instruction의 destination register 번호와 뒤 instruction의 source register(2개중 하나라도) 번호가 같아질때 forwarding을 한다 (단 ex/mem.regwrite와 mem/wb.regwrite 시그널이 1이어야 함).
어느 pipeline register에서 forwarding을 할지는 뒤 instruction의 source가 앞의 instruction들 중 어떤 instruction과 hazard관계인지가 결정한다.
forwarding으로 해결할 수 없는 경우 (stall이 불가피하게 필요한 경우)
사진에서처럼 lw instruction의 destination register가 바로 뒤 instruction(and)에서 source register로 사용될 경우, 해당 destination register는 mem/wb 파이프라인에 새로운 값이 써지므로, 직후 instruction의 source register값으로 이 값을 forwarding해오는것은 시간의 역순이어서 물리적으로 불가능하다.

이런 경우 pipeline stall을 해주는데, MemRead가 1이고(MemRead가 1인 instruction은 lw가 유일하다.) ID/EX.RegisterRt가 IF/ID.RegisterRs 나 IF/ID.RegisterRt중 같은것이 있는지 확인하는 방식으로 hazard를 detection한다. (in cc3)

stall을 하는 방법은 ID/EX register의 control signal 9bit를 모두 0으로 만들고, pc와 IF/ID register의 업데이트를 막아서 같은 명령어가 한번 더 decode되고, 한번 더 fetch되게 하는 것이다.
pipeline stall을 피하기 위한 code scheduling
이것은 하드웨어가 해줄 필요는 없고 소프트웨어(컴파일러)가 해주면 된다.
컴파일러가 code scheduling을 통해 instruction의 순서를 효율적으로 바꿔주어 stall을 최소화할 수 있게 해준다. (단 data hazard가 일어나는 상황, 그리고 hazard의 해결 방법은 프로세서의 설계에 따라 다르기 때문에 이를 위해서는 컴파일러가 하드웨어를 알아야 한다. 그래서 현대의 많은 프로세서들의 성능에 있어서 컴파일러의 역할이 매우 중요하다.)

 

 

3. Control hazard (Branch hazard)

  • branch명령은 flow를 변경한다. (fetch할 다음 명령어의 주소는 branch 조건에 따라 달라진다.)
  • pipeline stall을 최소화하기 위해 branch 여부를 예측한다. 
    • static branch : taken 또는 not taken으로 고정해서 예측하는 것. (mips에서는 static하게 not taken으로 예측함.)
    • dynamic branch : 프로그램의 수행 history(최근 이 branch가 taken되었는지 아닌지)를 보고 dynamic하게 결정을 바꿀 수 있는 것.
mips에서 static하게 branch not taken으로 예측했을 경우의 문제점
branch가 not taken된다고 예측하고 이미 뒤의 instruction을 3개나 fetch했는데 CC5에 pc가 업데이트되면서 그제서야 branch여부를 발견하게 됨. 그럼 이전에 있던 세개의 instruction은 모두 flush(버블이 됨)가 되어야하는데 그러면 performance가 너무 나빠짐.. 그럼 이런 flush를 어떻게 최소화할 수 있을까? 
하드웨어 수정 : BTA를 계산하는 adder + 레지스터값을 비교하는 Comparator를 ID Stage로 옮긴다!
(branch가 일어나는지 여부를 더 빨리 알아야 하기 때문이다.)
9개의 control signal중 branch control signal이 1이고, register comparator의 출력이 1이면 and 연산에 의해서 IF.Flush가 1이 되고, 그러면 IF/ID register의 instruction부분에 0x00000000이 써진다. (nop instruction)

 

* 본 포스팅은 국민대학교 소프트웨어학부 컴퓨터구조 2022-2학기 수업 내용에 대해 정리한 것입니다. 참고 자료는 임은진 교수님의 수업 자료이고, 참고 도서는 한티미디어 컴퓨터 구조 및 설계 6판입니다.