컴퓨터 구조 6

강한친구·2021년 11월 3일
0

Computer Architecture

목록 보기
7/12

파이프라이닝

정의

기존의 싱글사이클과는 다르게 각 단계별로 독립화시켜서 처리할 수 있도록 한다. 각 단계를 거칠때마다 클락을 하나씩 줄 수 있고, 클락사이클 하나당 명령어를 하나씩 처리한다.

멀티플 사이클이 되면 하나의 명령어를 기준으로 봤을때는
IFetch Dec Exec Mem wb 까지 5단계 필요함

기본적으로 멀티플사이클 사이에는 약간의 처리가 들어가야해서 단 한개의 명령어만 두고 비교하면 싱글사이클이 좀 더 시간이 빠르다. 다만, 사이클을 나눴을 때 놀고 있는 부분이 있고 그 부분에 다음 명령어들을 그 자리에 넣어서 작동함 따라서 총 작동 시간은 줄어들게 된다.

5단계 파이프라이닝
9단계 파이프라이닝
11단계 파이프라이닝
세분화 할수록 단위시간당 처리하는 명령어 횟수는 훨씬 더 늘어남


파이프라인 MIPS 프로세서

Throughput – 단위시간단 처리되는 일의 양, 초에 몇 개의 명령어를 처리하느냐 파이프라이닝을 하면 싱글사이클 데이터패스보다 많이 처리한다

Latency – 하나의 명령어를 기준으로 봤을 때, 하나의 명령어가 처리되는 시간
멀티사이클이 단일사이클보다 하나의 처리시간이 더 길어진다. 즉 레이턴시가 늘어난다

sw에서 wb는 아무것도 안하지만 명령어는 소비한다. 따라서
몇몇 명령어에서 몇 단계들은 낭비되는 사이클이다

파이프라인 control signal

  1. Instruction Fetch
  • PC에 쓰는 제어신호는 항상 인가되어 있으므로, 이 단계에서는 특별이 제어할것이 없다
  1. Registration Decode/ Encode
  • 이전 단계와 마찬가지로 매 클럭 사이클마다 같은 일이 일어나기에 설정할 제어선이 없다
  1. ALU
  • RegDst, ALUOp, ALUsrc이다. 이 신호들은 ALU 연산을 선택하고, Read data 2의 부호확장된 수치값 중 하나를 ALU로 입력선택한다.
  1. Memory Access
  • Branch, MemRead, MemWrite를 쓴다. 각각 beq, lw, sw일 때 신호된다.
  1. WB
  • MemtoReg와 RegWrite이다. 전자는 레지스터 파일에 ALU 값을 보낼것인지 메모리값을 모낼것이닞 결정하며, RegWrite는 선택된 값을 레지스터에 쓰게 하는 신호이다.

파이프라인의 3가지 문제

  1. 구조적 문제
  • 다른 두 명령어가 같은 자원을 사용하려 함
  1. 데이터 문제
  • 준비가 되기 전에 데이터를 사용하려 함
  1. 컨트롤 문제
  • 브랜치 점프 같은 이동명령어에서 발생하는 문제
    기존의 명령어들은 pc가 이미 다음 값을 가지고 있고 순차적으로 작동함

구조적 문제

그림에서와 같이 각 클락별로 동시에 실행하기 때문에,
메모리소자에 동시에 접근하고 이떄 계산된 메모리가 덮어씌워지면서 잘못된 값을 가지고 오게 된다.

해결 : 메모리를 분리한다.
Inst, data 를 분리해서 서로 맞는곳에서 가지고 오게 한다

레지스터의 경우 동시의 두개의 명령어가 하나의 레지스터에 접근함 하지만 레지스터는 2개를 둘수가 없다.

클락이라는건 항상 up down이 있다 따라서 이를 두개로 구분해서 firshalf에서는 데이터를 쓰도록 하고, second half에서는 데이터를 읽도록 설정한다

데이터 문제


그림에서와 같이 데이터가 써지기 전에 읽어들이는 명령어가 실행되면서 오류가 발생하게 된다.

뒤의 명령어들이 앞에 결과를 받아서 계산을 수행하도록 되어있음
2개 이상 떨어진 명령어는 큰 문제가 없음
하지만 그 범위 내라면 문제가 생김

LoadUse Hazard
1. Stalling (Freezing) the pipeline

  • 두개를 비워주고 실행한다
  1. (internal) forwarding
  • 데이터를 포워딩 해준다
  1. Compiler scheduling
  • 컴파일러 단계에서 명령어 순서를 바꿔서 소스결과를 바로 쓰는 그런 결과가 생기지 않도록 하자

스톨

중간에 거리를 벌려주는 스톨을 쓴다. 스톨이 많이 사용될 수록 성능이 저하된다. 따라서 권장하지 않는 방법이다.

포워딩 : 전달

전달해주는 Path를 작성한다.
계산결과는 레지스터에 들어가기 전에 이미 ALU를 통해 나와있다. 따라서 이 결과를 DM Reg에 들어가기전에 다음 ALU로 바로 넣어버린다.

하지만, Lw 메모리로부터 읽어오고 연산에 쓰는 시퀀스에서는 ALU의 연산결과가 오는게 아니라 data memory에서 읽을 때 온다.
따라서 그 다음 계산에서 미리 땡겨쓸수가 없다
따라서 필수적으로 Stall을 한번 해서 무조건 수행해야한다

결론

결론 ALU연산에서는 스톨없이 포워딩으로만 가능하다
LW연산에서는 스톨 한번하고 포워딩을 해줘야한다
이 문제에서는 패스를 만드는게 제일 중요하다

컴파일러 스케쥴링


마지막 해결책은 컴파일러에서 미리 방지해주는것이다. 그림과 같이 순서를 조정하여 최적화하낟.

컨트롤 문제

Exe를 해봐야 항상 결과가 나오고 어디로 갈지 알 수 있음

해결책
1. 브랜치의 결과가 나올 때 까지 대기 버블

브랜치 예측

버블을 줄여줄 수 있는 기법이 있음 (conditional branch)

해석이 디코더 단계에서 해석이 되기 때문에 그 다음 명령어는 항상 pc + 4 pc + 8이다. 따라서 참이 되면 항상 지정한 위치로 flow가 가도록 한다.

예측이라는건 브랜치가 취해지지 않은 경우를 하는것이고 다음 명령어 PC+4를 가져온다. Not taken 이 맞았으면 정상수행을 하고 만약 taken 된거면 지워버리고 계산되는 라벨로 PC값을 변화시키고 그쪽으로 간다.

어차피 예측을 안하면 무조건 다음 결과를 날려야한다
예측을 함으로서 예측이 맞으면 성능이 향상되는거고, 예측이 틀리면 그냥 원래대로 bubble을 넣어서 해결한다

For loop, if 같은 조건의 경우
평소의 패턴에 맞게 예측해서 조금 더 정확한 예측이 가능하다

다양한 예시들

lw





레지스터가 잘못 쓰일수 있기 때문에 앞에서 가지고 와서 끝까지 전달하고 다시 지정해주게 된다.
IF/ID라 파이프라인 레지스터에 있는 명령어가 쓰기 레지스터 번호를 제공하고 있는데 이는 사실 적재 명령어보다 상당히 뒤에 있다. 따라서 적재 명령어에 목적지 레지스터 번호를 잔직할 필요가 있다. 이에 미리 주소지를 각 register에 5비트 공간을 마련해 넣어주는것이다.

순서대로 fetch, decode, execution, memory, wb 상태이다.

하지만 여기서 결과가 나오기전에 값을 가져다 쓰는 상태가 생길 수 있다. 이것이 바로 data hazard 이다 .

Data Hazard 고려한 그림

ALU와 ReadData가 ALU로 들어가야한다.

Control Signal

컨트롤 시그널 역시 각 단계별로 분리해야한다.

전체를 연결하면 다음과 같다

각 명령어에 맞는 control bit를 보내준다

Grande Final

다음과 같은 조건이 있을 때,


우선 첫번째 fetch 단계이다.

별다른 특징은 없다

첫번째는 값이 있고 두번째는 사용하지 않는다.
20은 sign을 통해 전달된다.
그리고 레지스터 주소값 10을 전달한다

컨트롤 시그널은 lw라서 3개를 지정한다.
src는 20이라는 array 소스값을 써야해서 1
alu op = 00
write register 의 위치의 mux값인 0 Ekfktj 0001이 ex의 control signal이다.

Write 0, Read 1, branch 0 따라서 Mem control = 010

wb에서는 register write 값을 판단하는데 이는 1 memory write 역시 1 따라서 11 이다.

다음 명령어인 sub가 decode단계로 왔다.
lw는 ALU 연산에 들어가서 더이상 해줄것이 없다

Control은 ALU는 sub를 위한 01
EX는 1100 이다. 주소선택 mux와 register 값 선택 0 이다.
Mem에서는 할일이 없어서 전부 000이다.
WB에서는 ALU연산의 결과를 WB해야한다. 따라서 Write 1 Read 0 10

그리고 동시에 add가 Fetch 된다

어드레스를 읽어서 값을 저장하고 register 값을 아래쪽 path를 통해서 가지고온다.

이런식으로 각 단계에 맞는 control 시그널을 따로 보내주면서 동시에 계산을 수행한다.

0개의 댓글