Computer Science 기본 지식/컴퓨터 구조

[컴퓨터 구조] 6. 명령어 파이프라이닝

로파이 2021. 4. 18. 16:32

기본적인 단일 사이클에서 명령어 단계 (4단계)

1. 명령어 인출(IF) : 다음 실행될 명령어를 기억장치로부터 가져온다.

2. 명령어 해독(ID) : 제어 유닛의 해독기에서 명령어의 opcode를 해석한다.

3. 오퍼랜드 인출(OF): 연산에 필요한 오퍼랜드의 데이터를 기억장치로부터 인출하는 단계

4. 실행(EX): 해독기에서 정해진 연산을 수행하는 단계

 

--- RISC-V 명령어 단계 (5단계)

1. 메모리에서 명령어를 가져온다.

2. 명령어를 해독하는 동시에 레지스터를 읽는다.

3. 연산을 수행하거나 주소를 계산한다.

4. (필요하면) 데이터 메모리에 있는 피연산자에 접근한다.

5. (필요하면) 결과값을 레지스터에 쓴다.

 

예시)

산술 연산 명령어

 

add x1, x2, x3

 

1. 명령어를 메모리에서 가져오고 PC를 증가시킨다.

2. 두 레지스터 x2, x3를 레지스터 파일로부터 읽는다.

3. ALU는 읽어드린 두 레지스터와 opcode 부분을 사용하여 ALU 제어신호를 만든다.

4. ALU의 결과값이 레지스터 파일의 목적지 레지스터(x1)에 써진다.

 

적재 명령어

ld x1, offset(x2)

 

1. 명령어를 메모리에서 가져오고 PC를 증가시킨다.

2. 레지스터 x2 값을 레지스터 파일로부터 읽는다.

3. ALU는 레지스터 파일에서 읽어 들인 값과 12비트 오프셋을 합한 값을 구한다.

4. 계산 결과의 주소에 대해 메모리를 접근하여 값을 가져온다.

5. 데이터를 x1에 적재한다.

 

조건부 분기 명령어

beq x1, x2, offset

 

1. 명령어를 명령어 메모리에서 가져오고 PC 값을 증가시킨다.

2. 두개의 레지스터 x1과 x2를 레지스터 파일로부터 읽는다.

3. ALU는 레지스터 파일에서 읽어 들인 두 개의 값을 사용하여 하나의 값에서 다른 값을 뺀다. 오프셋을 확장한후

1비트 왼쪽 shift한 값에 PC 값을 더한다. 결과값이 분기 목적지 주소가 된다.

4. 덧셈기의 결과를 PC에 저장할지 분기 여부를 ALU에서 뺀 값이 0인지를 보고 판단한다.

 

파이프 라이닝

"자주 생기는 일을 빠르게 하라"는 원칙으로 여러 명령어를 중첩하여 실행하는 구현 기술이다.

세탁물에 비유한 파이프 라이닝 과정

어떤 옷을 세탁하기 위해 다음 4단계를 거친다고 하자.

  1. 세탁기에 세탁물을 담는 1단계
  2. 세탁후 꺼낸 옷을 건조기에 담는 2단계
  3. 건조된 옷을 개는 3단계,
  4. 옷장에 정리하는 4단계

4 단계를 세탁물이 끝날 때마다 새로 시작하다면 4단계 x X (세탁해야하는 빨래물 수)의 시간이 걸린다. 만약 세탁기의 세탁후 바로 다음 빨래물을 투입한다면 그리고 건조기도 마찬가지로 세탁된 빨래물을 바로 건조기에 투입하는 식으로 단계에 해당하는 일을 쉬지않고 진행할 수 있다. 이 일은 대략적으로 빨래물 수 X에 비례하게된다.

명령어 수 X가 크다면 보면 X / 4 x X의 비율로 명령어 파이프라이닝 단계 수에 비례하여 시간이 줄어든다.

 

실제 명령어 파이프 라이닝

파이프 라이닝 기술은 명령어 인출 이후 다음 명령어를 인출할 수 있게 한다. 단일 사이클의 경우 다음 명령어 인출 까지 800ps가 걸리지만 파이프 라이닝된 명령어는 다음 명령어 인출까지 200ps에 가능하다.

 

파이프라인 해저드

파이프라인으로 여러 단계가 병렬적으로 실행될 수 있지만 상황에 따라 연속적 파이프라인이 불가능한 상황이 존재한다.

 

구조적 해저드 (Structural Hazard)

같은 클럭 사이클 내에서 하드웨어 적으로 실행 불가능한 두 명령어 조합이 동시에 실행될 때 발생한다. 한 명령어는 같은 주소의 메모리의 데이터를 접근하고 한 명령어는 같은 주소의 메모리의 값을 가져온다면 구조적 해저드가 발생한다. 

 

데이터 해저드 (Data Hazard)

어떤 명령어의 피연산자가 그 이전의 명령어의 연산 결과에 의존적일 때 발생한다.

예시)

 

add x19, x0, x1

sub x2, x19, x3

 

그 예로 add 명령어의 결과가 sub 명령어의 피연산자로 바로 사용되는 경우가 있다. sub 명령어가 실행 하려면 add 명령어가 4단계를 마치고 x19에 값을 쓸 때까지 기다려야만 한다. 이러한 병목 현상을 줄이기 위해 한 명령어의 결과를 다른 명령어의 입력으로 4단계 이전에 전달할 수 있는 방법이 있다. 이를 위해 특별한 하드웨어를 추가하여 값을 전달하는 방식을 전방전달(forwarding) 혹은 우회전달(bypassing)이라고 한다.

 

add 명령어 모식도

각 하드웨어의 오른쪽 혹은 왼쪽이 색칠될 수 있는데 오른쪽은 읽기, 왼쪽은 쓰기가 이루어지는 것이다. 명령어 인출 단계 IF에서 명령어가 읽혀지고 제어 유닛의 해독기에서 명령어가 해독된다. 명령 코드 opcode에 따라 실행 EX가 이루어지며 해당 결과가 메모리에 써진다면 MEM, 그리고 레지스터에 다시 쓰는 WB을 메모리 블록으로 나타낼 수 있다.

add 명령어는 연산 결과를 메모리에 따로 저장하지 않기 때문에 MEM은 칠해지지 않으며 4단계에서 레지스터에 write하기 때문에 WB 블록이 왼쪽으로 칠해진다.

 

전방 전달

전방 전달

전방 전달은 계산 결과를 WB 단계 이전에 다음 명령어의 피연산자로 전달하고 있다.

 

Load and Use data hazard

적재-사용 데이터 해저드

 적재 데이터 해저드는 적재 연산의 특성상 실제 메모리에서 레지스터에 옮기기 전까지 전방전달을 할 수 없다. 위 예에서 x2 주소에 저장된 값을 x1 레지스터에 적재하는 시점에 다음 명령어는 실행 단계가 실행되어야 하는데 x1 데이터 의존성으로 어쩔 수 없이 1 클럭 주기의 지연이 발생하게 된다. 이러한 지연을 파이프라인 지연(pipeline stall) 혹은 거품(bubble)이라고 한다.

 

제어 해저드 (Control Hazard)

다음 실행 명령어가 이전 명령어의 결과값에 따라 달라질 수 있을 때 발생한다. 조건부 분기 명령과 같은 명령어는 다음 명령어가 어떤 것 일지 결과가 나오기전 까지는 모르기 때문에 지연이 발생하게 된다.

 

Stall On Branch (분기 지연)

분기 지연

 beq x1, x0, 40 명령어의 결과에 따라 결과가 참이라면 40번 오프셋의 상대주소의 명령어를 가져와야한다. 실제 한 단계의 지연이 발생하는 것을 볼 수 있다.

 

제어 해저드의 해결 방법

1. 대부부의 컴퓨터는 조건부 분기 명령어를 다루기 위해 예측을 사용한다. 간단한 방법은 조건부 분기가 항상 실패한다고 예측하는 것이다. 

2. 지연 분기: 실제 분기 사이클이 한 사이클 늦게 일어나도록 한다. 조건을 계산한 다음 조건 분기와 관련 없는 명령어를 실행한다. 그 이후 한 사이클 늦게 조건 분기가 일어나 PC 값을 바꾸고 분기 목적지로 안전하게 분기된다.

 

참고 : Computer Organization and Design RISC-V edition