컴퓨터(Computer Science)/컴퓨터구조(Computer Arichitecture)

Pipeline Hazard & Solution[컴퓨터구조]

게임이 더 좋아 2021. 6. 19. 02:31
반응형
728x170

 

 

Hazard는에당 아자르 할 때 스펠과 같다.

하지만 뜻은 여기에서 다르게 쓰인다.

 

위험! 이 아니라. 고쳐야 할 문제점이라고 생각하자.

Hazard를 발견하는 것도 좋은 방법이다. 알아야 고칠 거 아냐

 

아무튼 이번엔 파이프라인에서의 해저드를 알아보자

 


여기서 해저드란

 

파이프라이닝을 방해하는 상황을 말한다.

ex) 다음 싸이클에 다음 명령이 수행 불가능한 경우

 

 

크게 3가지로 나눈다.

Structural Hazard

 

Data Hazard

 

Control Hazard

 

1. 해당 자원이 필요한데 다른 instruction이 사용하고 있다거나 그런 경우다.

A required resource is busy

 

2. 앞선 명령어가 해당 데이터에 대한 값을 반환하지 않아서 사용을 못하는 경우 

Need to wait for previous instruction to complete its data read/write

 

3. 앞선 명령의 결과에 따라 실행이 될 수도 있고 안 될 수도 있는 경우

Deciding on control action depends on previous instruction.

 

 

하나하나 살펴보자

 


 

구조적 해저드부터

 

 

자원 사용에 있어 충돌이 나는 것이다.

 

만약 single memory라고 하고

Load 가 memory에 access하고 있으면

다음 명령어는 Load가 memory에 접근하고 있는 동안은 stall할 수 밖에 없다는 것이다.

** bubble은 수행되지 않고 넘어가는 구간을 의미한다.

 

 

그래서 파이프라인에서는

instruction에서의 메모리와 data 의 메모리를 구분을 하게 해놨다.

일반적으로 Resource를 구분하거나 추가시켜서 해결하는 방법이 있다.

 

메모리와 레지스터 해저드의 해결법이 조금 다르다.

 

 


 

데이터 헤저드다.

 

 

 

이전 instruction의 결과에 영향을 미치면 그렇게 된다.

즉, 해당 r1레지스터의 결괏값이 sub instruction에 영향을 미쳐서 나오는 해저드다.

 

ID와 WB을 같은 단계에 놓을 수 있는 이유는

쉽게 말해서 쓰려는 값 자체가 sub가 쓰려는 값과 동일하기 때문이고

또한 레지스터는 빠르기 때문에 write를 클럭의 절반 시간동안 하는 것이 가능하다.

 

하지만 이렇게 해결하는 것을 원하지 않는다.

다른 방법이 존재한다.

 

두 개의 이름을 가지지만 포워딩이라고 하나로 퉁쳐서 쓰고는 한다.

 

 

즉, 결괏값이 나오자마자 해당 값을 바로 사용하는 것을 의미한다.

앞선 경우 EX가 끝나면 결괏값이 나오기 때문에 WB까지 가지 않고도 그 값을 사용할 수 있다는 말이다.

 

 

ALU에서 나온 결과, 즉 EX단계 후에 바로 사용하는 것이다.

하지만 이 값을 사용하려면

Datapath에 추가적인 wire를 사용해야한다.

 

또한 Load Use 해저드가 있다.

Load가 있을 때의 해저드다.

 

왜 구분하느냐?

포워딩을 하더라도 stall을 피할 수가 없어서 그렇다.

 

 

 

결국 Data는 MEM에서 레지스터로 들어오게되는데

결국 EX 단계에 필요하니까

어쩔 수 없이 다음 명령어는 실행할 수 없는 bubble이 생긴다는 것이다.

 


 

그래서 코드를 짤 때 stall을 피하게 짜는 것도 있다.

 

 

왼쪽에서 stall이 발생하므로 미리 다 lw해놓고... 연산을 하겠다는 것이다

2 cycle이나 줄어버렸다.

 

해저드를 피하는 방법이 forwarding이라는 wire를 이어서 물리적 측면 뿐만 있는게 아니라

코드를 짜서 피하는 방법도 있다는 것이다.

 

 


 

마지막은 Control 해저드다.

 

 

가장 대표적인 예가 Branch instruction이다.

즉, branch로 가야 그 다음 명령어가 무엇인지 알 수 있다.

조건에 부합하면 target address로 가는 것이고 아니면 그냥 다음 명령어가 실행되는 것이다.

 

다시 말해서 branch에 다음에 오는 instruction을 명확하게 하지 않으면 오작동할 수 있다는 것이다.

 

그래서 MIPS에서는 ID stage에서 장치를 추가해서 Target address를 구하게 했다.

**(원래는 ALU,EX)

 

 

즉, 다음 IF 단계가 실행되기 전까지

해당 ID에서 branch 결과를 기다려서 얻고 나서 결정해야한다는 말이다.

그래서 1번은 stall이 걸리게 된다.

 

하지만 하드웨어를 추가해서 ID에서 값을 얻게 되어서 1번만 stall이 된 것이지

ALU에서 얻게 되었으면 사실 2 번의 stall 이 될 뻔했다.

 


 

 

그래서 이번 stall도 피하고 싶어서 연구자들이 많이 연구를 했고

그중 대표적인 Solution이 

바로 Prediction이다. 

 

 

맞으면 바로 진행되니까 stall이 발생하지 않고

틀리면 stall을 발생시키면 되고

해보고 안되면 말지 이런 느낌이다.

 

예를 들면

 

 

맞으면 좋고

아니면 말고

 

하지만 이 예측도 아무렇게나 하는 것은 아니다.

 

2가지 종류의 예측을 한다.

 

1. Static -> 예측이 고정되어 있음

2. Dynamic -> 최근 실행 결과를 바탕(history)으로 예측 

++ history를 저장하는 메모리장치가 필요

 

 

반응형
그리드형