컴퓨터 구조론

[컴퓨터 구조론]7.Pipelining Bascis

myjeongjun 2025. 1. 6. 19:13

 

(이전 챕터인 singlecycle과 multicycle은 회로 부분을 좀 더 공부하고 작성하도록 하겠습니다.)

 

 

single cycle에서의 문제점: 긴 instruction이 존재하면 그 instruction에 맞춰서 cycle time도 맞춰야한다. 모든 리소스들은 1가지 용도로 밖에 사용못한다.

 

파이프라인은 1사이클당 한 instruction이 끝나게 되어있다.

처리과정은 5단계로 나눠지는데,

1.IF : PC를 이용해 instruction을 가져오는단계

2.ID : 말그대로 instruction을 디코드하고 register도 가져온다.

3.EX:ALU를 사용하는 step

4.MEM :메모링에 Acess하는 단계인데 load나 store같은 instruction에서 필요한 단계이다 R-format같은경우 이 step에서 아무것도 하지않을수도있다.

5.WB:target register에 쓰기작업

 

Pipelined Execution은 다른 Excution들과는 다르게 항상 5cycle을 가진다.

이상적인 pipeline과정

하지만 이러한 구조로인해 크게 3가지의 문제가 발생할 수 있는데,

1.structural Hazard

2.Data Hazard

3.Control Hazard

하나씩 알아보자

먼저 structual Hazard는 만약 위 그림의 가장 처음에 들어온 명령어가 load or store라면 흰색으로 표시된 MEM단계에서 메모리에 Access를 시도할 것이다. 다음 명령어가 load, store거나 아니어도 IF단계에서 instruction을 가져오기위해 메모리에 접근하기때문에 여러 명령어가 동시에 메모리에 접근하는 문제가 발생할 수 있다.

 

또한 WB단계 기준으로 봐도 WB는 쓰기단계이지만 바로 아래부터는 읽는 작업을 수행할수있기때문에 문제 발생의 여지는 충분해보인다.

 

그러므로 해결법중 하나로 resource를 replicate를해서 instruction 메모리, Data 메모리를 분리 시켜놓아 접근이 충돌하지 않게하는 방법이있다.

 

 

RAW의 약자는 read after write로 말 그대로 사용해야하는 값이 쓰여진다음에 읽어야하는데 먼저 읽어버리면 순서가 잘못되었다는것이다

명령어를 분석해보면

ADD $1 $2 $3: 2의 값과 3의값을더해서 1에저장해라

SUB $4 $1 $5 : 1의 값과 5의값을빼서 4에 저장해라

 

SUB를 계산하기 위해선 $1의 값이 필요한데, 파이프라인 특성상 쓰기 작업은 맨뒤에 이루어지므로 바로 다음으로 SUB명령어가 와버리면 순서가 맞지 않을수있다는 점이다.

 

해결법으로 3가지를 제시했는데, 차례대로

 

Freezing the pipline


말그대로 서순을 맞추기위해 다음 명령어의 일부를 얼리고 그 작업이 가능할때 실행하는것이다. 이러면 파이프랑인 동작의 장점을 최대로 보지못한다는 단점이 있겠지만 값을 잘못불러오는 일은 방지 할 수있다.

 

Forwarding 

이 방식은 가장 효율이 좋은 방식이라고 설명한다. 

 

 

 

ADD명령어에서 EX단계는 ALU가 관여하여 계산을 마치는 단계이다. 그 계산된 값을 WB단계까지 끌고가서 쓰기작업을하는것인데

굳이 계산한값을 WB까지 끌고가지말고 바로 아래로 보내주도록 구현하면 cycle의 손해도 없는 방식이다.

 

Load명령엉의 경우 memory를 읽어야하는 작업이므로 MEM을 마치고 바로 내려줄수있다.

 

Complier Scheduling

컴파일러가 잘 스케쥴링해서 파이프라인의 손해가 없게끔 의존관계가 없는 명령어들을 배치시키는 것이다.

 

 

 

Control Hazard

한가지 예로 branch 명령어는 명령어가 끝나야지 다음 Instruction이 조건을 만족해서 target으로갈지 조건을 만족못해서 PC+4명령어어로 이동할지를 알수 있기때문에 발생하는 문제로

None - sequantial하게 PC값이 변경되는 instruction에대해 발생 할 수있는 문제라고 보면된다.(jump,branch,call/return)

 

이런 control Hazard를 해결하는 3가지 방법이 존재한다.

 

Optimized branch processing

1.조건을 간략화 시킨다.

 

2.target adress를 빨리 계산하고 2cycle에 branch를 끝낼수있게 해보자는 식으로 

애초에 branch를 짧게만들어서 손해를 줄이는 방법이다.

 

Branch Prediction

일단 branch바로 다음 명령어로 PC +4를 집어넣고 보는것이다.

 

이랬을때 branch가 taken이 안되었으면 그대로 가면되는것이고, 만약 taken이 되어버렸다면 다음 instruction은 멈추는것이아니라 아예  없어져야할 대상이되므로 nop로 만들어버린다.

 

Delayed Branch

이건 branch instruction의 semantics자체를 바꾸는 방법으로, 기존에는 branch가 taken되면 바로 target으로 이동해야하는데,

semantics를 바꿔서 무조건 다음 instruction을 실행후, taken인지 untaken인지에 따라 행동하게 만든것이다.