다음 단계로 넘어가지 못하는 상황은 세 가지가 있다.
1. 구조적 해저드(Structural Hazard)
lw 명령어로 데이터 메모리에서는 read하려고 할 때(MEM),
IF 에서 다음 명령어를 메모리에서 가져오려고 한다면 둘이 충돌이 나게 된다.
만약 메모리가 하나밖에 없다면, 데이터 메모리를 먼저 사용한 다음에, IF에서 바로 명령어를 가져오지 않고 한 타임 쉰다. (pipeline stall 이라고도 한다.) 그리고 빈 공간을 bubble이라고 부른다.
IF | ID | EX | MEM | WB |
lw | ||||
add | lw | |||
sub | add | lw | ||
(bubble) | sub | add | lw | |
beq | (bubble) | sub | add | lw |
이 문제때문에, Instruction Memory, Data Memory를 분리하고, ALU 말고도 PC를 계산하는 adder, 주소를 계산하는 adder를 또 추가해줬다.
잘 설계된 파이프라인에서는 구조적 해저드가 없다.
2. 데이터 해저드(Data Hazard)
데이터 해저드는 Data dependence이면서, 두 Instruction이 충분히 가까울 때 발생한다.
해결하는 방법은 간단하게 두 Instruction의 거리를 벌리면 된다.
2-1 Stalling(Hardware)
구조적 해저드문제처럼 하드웨어를 추가해주거나,
거리를 벌리고 그 차이만큼 bubble을 넣어준다.
2-2 NOP(Soft)
거리를 벌리고 그 사이에 NOP으로 채운다.
하드웨어 추가가 필요없지만 두 Clock을 낭비하게 된다.
2-3 Code Schduling(Soft)
의존성에 문제가 없게 앞이나 뒤에 있는 Instruction을 바꿔준다.
문제가 없는 명령어를 찾을 확률이 낮다.
2-4 Forwarding(hard)
레지스터 뒤에 쓸 때까지 기다리지 않고 바로 다음 명령어한테 전달한다.
그림을 보면 쉽게 이해할 수 있다.
load-use data hazard는 forwarding이라도 어쩔 수 없이 기다려야 한다.
3. 컨트롤 해저드(Control Hazard)
컨트롤 해저드는 Branch상황에서 발생한다.
Branch는 MEM에서 결정이 되는데 위 표를 다시 보면
IF | ID | EX | MEM | WB |
beq | ||||
add | beq | |||
sub | add | beq | ||
and | sub | add | beq | |
(new PC) | (bubble) | (bubble) | (bubble) | beq |
beq의 결과가 참이라서 다른 곳으로 점프를 하게 된다면 그동안 Fetch했던 명령어들이 전부 쓸모가 없게 된다.
해결하는 방법으로는
3-1 Stall on Branch
Branch를 만나면 Stall을 하는 것이다.
이렇게 되면 매번 Branch마다 3 Clock을 낭비하게 되서 좋은 방법은 아니다.
3-2 Static / Dynamic Prediction
Satic Prediction은
1. Assume branch taken
2. Assume branch not taken
3. Prediction by opcode
4. Prediction by direction 이 있다.
1,2는 taken이다 아니다로 밀고 가는 단순한 방법이고
3번은 beq가 7 : 3 으로 많이 taken이 되면 taken으로 추측하고
bne이 1 : 9로 not taken에 많이 사용되면 not taken으로 추측한다.
4번은 방향에 따라서 결정하는데 거꾸로 올라가는 것은 loop인 경우가 많아서 branch인 경우가 많다.
Dynamic Prediction은 Runtime에 분석한다.
학부 수준으로는
1. Branch prediction buffer
2. Branch target buffer 정도 공부한다.
Branch prediction buffer(branch history table)는 최근에 taken인지 not taken인지를 1bit에 기록한다. 이 경우에는 둘 이상의 beq가 있으면 정확도를 80%밖에 보여주지 못해서 2bit의 table을 만들었다.
2bit같은 경우는 한 번 정도 not taken이어도 그전에 taken이었으면 계속 taken을 유지한다.
Branch target buffer는 Branch Address가 있어서 주소를 계산할 필요 없이 바로 점프할 수 있다.
Docker에서 WordPress upload_max_filesize 변경 (0) | 2019.09.25 |
---|---|
WordPress Plugin 취약점 분석 (0) | 2019.09.19 |
웹 보안 - SQL 인젝션 (0) | 2019.08.22 |
컴퓨터구조 - 파이프라이닝 (0) | 2019.08.17 |
웹 보안 - 브루트 포스 (0) | 2019.08.16 |