전공/컴퓨터 코딩 데이터

[컴퓨터구조] RISC-V 파이프라인 data/control hazards

흔한 학생 2024. 11. 24. 14:53

컴퓨터구조 수업에서 RISC-V 기반으로 설명되어 있기에 리스크파이브 기반으로 파이프라이닝에서 발생하는 해저드에 대해 설명해볼 것이다. 우선 해저드 전까지 5-stage pipelining을 알아봤을 것이다. 이는 IF ID EX MEM WB 로 구성되어 있으며 각 단계 사이에는 레지스터가 존재한다. 

Pipeline Hazards

해저드는 structure hazard, data hazard, control hazard 세 가지 종류가 있다. 자세한 것은 아래에서 설명할테지만 우선 structure hazard는 하드웨어의 lag 렉으로 발생한다. 하드웨어 자원이 연산 중 충돌하여 발생한다.
data hazard는 data dependency에 의해 발생한다. 명령어가 특정 레지스터를 사용하여 수행할텐데, 파이프라이닝이라는 것이 단계별로 여러 명령어를 수행하는 것이니 같은 데이터(레지스터)를 참조할 수가 있다. 이때 이전 명령어에서 해당 레지스터에 대한 동작이 완전히 끝나지 않았는데 다음 명령어에서 같은 레지스터를 쓰려고할 때 발생한다.
control hazard는 conditional branch 상황에서 발생한다. 프로세서는 branch의 조건이 맞는지 틀린지 연산 전까지는 모르기에 해저드가 발생한다. 

Data Hazards

해저드 발생 예시

다음과 같은 예를 들어 설명하려고 한다.

add x12,x3,x4
sub x11,x2,x12

add 명령어에서는 레지스터에 값을 작성하는 WB에 x12에 대한 동작이 완료된다.
다음 명령어인 sub에서 ID stage에서 x12를 불러오기 때문에 2cycle 딜레이가 있어야 목표한 동작이 수행된다. 
(add 명령어가 WB stage에 있을 때 sub 명령어의 ID가 수행되어야 한다)

이러한 딜레이가 없다면 sub 명령어에 쓰이는 레지스터 x12의 값은 add 명령어가 수행되기 전의 값이 될 것이다.
그렇다면 이러한 딜레이는 어떻게 줄일 수 있을까?

forwarding 1

앞서 WB stage에서 x12가 저장된다고 했는데 이 값을 더 빨리 받아오는 것이다. 
생각해보면 사실상 x12에 저장될 값에 대한 연산은 EX stage에서 나온다. 이 값을 다음 명령어인 sub 명령어에서 사용될 수 있도록 하는 것이다.

add x12,x3,x4
sub x11,x2,x12

때문에 sub 명령어에서는 ID에서 x12를 받아오지 않고 EX에서 나온 결과값을 쓰는 것이다.
이렇게하여 딜레이를 없앨 수 있다.

forwarding 2 (load-use dependency)

앞의 예시처럼 R-type 명령어의 경우 EX에서 연산된 값을 가져와 사용할 수 있다.
하지만 ld 명령어의 경우엔 어떨까?

ld x1, 0(x2)
sub x4,x1,x5

위 코드를 보자.
ld의 경우 EX stage에서 메모리의 주소 연산이 일어나기 때문에 x1에 저장될 값을 EX에서 알 수 없다. 
최소 MEM stage 이후 알 수 있기 때문에 1cycle delay가 필수적이다.

이를 load-use dependency 에 의해 일어난다고 하며
delay가 발생할 때 수행되지 않는 stage는 NOP 명령어가 들어간다(no operation).
이는 파이프라인 레지스터에 0이 들어감을 의미한다.

HW 구조

Control Hazards