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

Datapath, Simple Implementation Scheme & Pipelineing [컴퓨터구조]

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

지금까지 배운 것은 다 이것을 위한 필수 지식에 불과했다.

진짜 이제부터 하나하나씩 뜯으면서 보자.

 


 

먼저 ALU에 대한 것 부터 배워야 한다.

**ALU Control은 4-bit 이다.

 

 

ALU를 Control 하는 2-bit가 있는데 (opcode에서부터 온다)

나머지는 Instruction의 funct에서 온다.

 

 

그것을 ALUOp 라고 한다.

 

 

ALUOp에 따라서 ALU가 뭘할지 정해준다.

 

ALU는 아래 3가지를 한다.

1. Load/ Store일 때 add를 해주고

2. Branch일 때 sub를 해주고

3. R 타입일 때 operand에 맞추어 연산하는 것은 ALU가 하는 역할이다.

 

즉, 우리가 ALU 를 컨트롤해서 Combinational Logic을 만드는 것이 컴퓨터 구조의 주 목표이다.

 


 

 

 

우선 알고넘어가자.

opcode는 항상 6비트를 가지면서

source register는 항상 읽는다.

또한 저 rd와 rt에 값을 write하게 된다.

또한 rt에서 값을 읽어온다.

offset이 있는 경우 sign-extend를 이용하더라.


 

실제로 ALU Control의 내부를 까보자면

 

이런 방식으로 

ALU Operation의 비트가 정해진다고 하겠다.

 


어...?

근데 Jump는  offset이 26비트인데...? 어떻게하는거지..?

 

그 때 말했다.

PC의 최상위 4비트를 가져오고

26비트를 left shift 2번해서 26 + 2 + 4로 target address(32-bit)를 만든다고 했다.

 

즉, opcode만으로 ALU에게 계산을 바로 시킬 수가 없다.

아래와 같이 한다.

(흐린 부분 말고 찐한 부분 보자)

 

 


 

 

 

그럼 그것을 Datapath 로 보면 어떨까??

 

 

저기서 컨트롤에서 나오는 모든 것이 1비트인데

ALUOp만 2비트로 나와서 ALU Control로 들어간다.

또한 저기 보면

Instruction의 하위 비트[5-0] funct가 ALU Control에 또 들어간다.

이 조합으로 4-bit ALU Control이 만들어지는 것이다.

 

조금 더 복잡해진 그림이 되었다.

 

각 신호들의 역할은 이렇다.

 

 


 

흠.. 뭔가 복잡한데 operation마다 약간 성능의 차이가 있을 것 같은데

앞서 Clock은 가장 긴 instruction에 맞춘다고 했단 말이지..?

** 명령에 따라 다른 클럭을 사용하는 것은 매우 어렵기 때문이다.

 

 

Load 가 긴 명령어 중 하나이다.

Load가 실행되면 레지스터 파일에 담긴 target address를 ALU를 거쳐 계산해

메모리로가서 그 데이터를 다시 레지스터에 가져온다.

 

 

 

이렇게 간단하게 구현하면 비효율이 발생한다.

그래서 우리는 파이프라이닝으로 이것을 극복하고자 하는 것이다.

 


 

파이프라이닝이란 무엇이냐?

 

예를 들어보자

 

4명이서 빨래를 해야한다.

만약 1사람씩 한다면 8시간이 걸린다.

 

 

그렇지만 파이프라이닝을 해서

작업을 겹쳐서하게 된다면

 

동시에 세탁기는 못돌리지만

친구가 빨래를 탈수할 때 내가 세탁기를 돌릴 수 있고

빨래를 널 때 내가 탈수를 할 수 있다는 말이다.

 

왜 그것이 가능할까?

왜 자원이 공유가 가능한 것일까?

해당 자원 사용이 다른 사용자에게 아무런 영향을 주지 않기 때문이다.

세탁기 쓸 때 탈수기 쓰면 탈수기 성능이 구려진다거나 그런 것이 없잖아??

파이프라이닝이란 것이 먼 개념이 아니다. 우리 주변에 일상에 있는 것들이다.

 

다만 저기서 명심해야할 점은

세탁도 안하고 탈수기를 쓰는 정신나간 사람은 없겠지..?

즉, 선행과정이 있기 때문에 저렇게 되는 것이다.

 

4가지에 대해선 파이프라이닝 한 것이  2.3배 빠르다.

 

하지만 이 작업을 계속하게 된다면

무한대를 어떻게 표현하지... 음... lim h -> 0  일 때 1/h 가 된다면...

아니 n이 발산한다면.. 해당 값은 4로 수렴하게되고

해당 값은 파이프라이닝의 개수에 근접할만큼 속도가 빨라진 것을 볼 수 있다.

 


 

그렇다면 MIPS의 파이프라인은 어떻게 될까?

 

아주 중요하다.

각 단계에서 무엇을 하는지가 정말 중요하다. 

 

 

IF -> Instruction Fetch

ID -> Instruction Decode

EX -> Execution

MEM -> access Memory

WB -> Write result Back

 

또한 Instruction마다 각 단계에 걸리는 시간이 다르다.

 

Data Access, 즉, 메모리에 접근하게 된다면 시간이 많이 걸린다.

뭐 100 ps 위아래로 차이면 별로 차이 안날 것 같은데??라고 생각할 수 있다.

 


 

음.. 그렇다면 빨래처럼 실제로

파이프라이닝을 한 것이 시간이 더 빠를까???

 

 

lw는 800 ps이지만

3번 실행한 것의 차이는

2400 vs 1400 이다.

실행을 많이할수록 차이가 벌어지겠지??

 

파이프라인을 꼭 해야하는 이유가 생겼다.

 


 

그렇다면 pipeline의 성능은 얼마나 좋은걸까??

 

 

하지만 앞서 말했다시피

가장 느린 instruction 클럭에 맞춰지기 때문에 조금 다르게 계산해야한다.

**만약 모두가 같은 instruction의 실행 시간을 가지고 있다면 좋겠지만 실제는 그렇지 않다.

 

그러니까 저기 위에 perfectly balanced pipeline은 그냥 꿈이다.

 

그래서 MIPS에서 파이프라이닝의 성능을 볼 때는

시간보다는 처리량, throughput 을 본다.

 


 

MIPS가 파이프라이닝에 적합한 이유

 

 

모든 명령어가 32bit이다 - > instruction fetch와 decode를 한 싸이클에 할 수 있다.

명령어의 포맷이 많지 않다. -> 한 스테이지에서 decode와 레지스터 접근이 가능하다.

Load/Store의 경우 3번째 단계에서 address를 구하고 4번째 단계에서 access를 하기에 나눠질 수 있다.

메모리 operands가 정렬되어있어서 메모리에 접근하는 것도 한 싸이클 내에서 된다.

 

여기서 싸이클은 우리가 단계로 나눴을 때 어느 한 단계에 걸리는 시간을 말한다.

 

 

반응형
그리드형