KOCW에 공개된 영남대 최규상 교수님 컴퓨터 구조 강의를 수강 후 정리한 내용입니다.
4.7 Data Hazards: Forwarding vs Stalling
- ALU Instruction에서의 data hazard는 RAW(Read And Write)를 할 경우 발생
- forwarding을 사용하면 해결 가능. 단, 언제 forward를 detection할 지 알아야 함
- Data hazard와 forwarding에 대한 설명은 이전 포스팅 참고
1. Detecting the Need to Forward
Data hazard가 발생하는 경우
- EX stage가 끝난 후에 forwarding를 통해 data hazard를 해결
- EX/MEM의 destination register number == ID/EX의 source register number
- EX/MEM의 destination register number == ID/EX의 target register number
- MEM stage가 끝난 후에 forwarding를 통해 data hazard를 해결
- MEM/WB의 destination register number == ID/EX의 source register number
- MEM/WB의 destination register number == ID/EX의 target register number
2. Double Data Hazard
- 두 번째 명령어의 $1값은 첫 번째 명령어에 따라 결정되고 세 번째 명령어의 $1은 두 번째 명령어에 따라 결정됨
- 가장 최근의 값을 사용. 즉 첫 번째 명령어에서 세 번째 명령어로 forwarding이 발생하면 안되고 두 번째 명령어에서 세 번째 명령어로 forwarding이 발생해야 함
- EX stage에서만 forwarding이 발생하도록 하는 것. 이렇게 하기 위해서는 EX stage에서는 hazard가 발생하지 않아야만 MEM의 hazard를 해결하기 위해 forwarding을 수행
3. Load-Use Data Hazard
- 첫 번째 cycle의 MEM stage가 끝난 후에야 $s2를 사용할 수 있는데, 두 번째 cycle에서 EX stage에서 $s2 변수가 필요하기 때문에 1 cycle stall이 발생
- ID stage에서 check
- ID stage의 ALU operand register number는 IF/ID.RegisterRs, IF/ID.RegisterRt에 의해 주어짐
- Load-Use data hazard가 발생하는 경우
- ID/IE.MemRead가 true이고
- ID/IE의 target register와 IF/ID의 source register가 같거나
- ID/IE의 target register와 IF/ID의 target register가 같은 경우
- Load-Use data hazard가 발생하는 경우 bubble를 추가해 stall을 발생시킴
4. How to Stall the Pipeline
- ID/EX register에 0 값을 추가. EX, MEM, WB가 모두 no-operation하게 됨
- PC 값과 IF/ID register 값이 update되면 안됨
- 해당 instruction의 decode를 다시 진행
- 다음 instruction fetch를 다시 진행
- 1 cycle stall 동안 lw 명령어를 위해 MEM stage에서 데이터를 읽는 것은 허용해야 함. 허용해줘야 다음 EX stage로 진행될 수 있기 때문
1. Stall/Bubble in the Pipeline
2. Stalls and Performance
- stall은 기본적으로 성능을 저하시키지만 정확한 결과를 얻기 위해서는 반드시 필요
- 따라서 hazard와 stall을 없애기 위해 코드의 순서를 바꾸는 과정이 필요하기 때문에 컴파일러는 pipeline structure를 정확히 알고 있어야 함
4.8 Control Hazards
1. Branch Harzard
- branch의 결과가 MEM stage에서 나오면 파이프라인에 의해 실행된 다음 명령어들은 잘못된 명령어를 실행한 것. MEM stage 후에 제대로 된 명령어를 수행하게 됨
- 잘못된 명령어를 없애기 위해서는 이 명령어들을 flush 해줌
- flush: control values의 값을 0으로 만들어주는 것을 의미
Reducing Branch Delay
- 하드웨어를 추가해 branch의 결과를 ID stage에서 알 수 있도록 함
- Target address adder와 Register comparator를 ID stage에 추가하면 branch의 결과를 ID stage에서 알 수 있음
2. Data Hazards for Branches
- comparison register가 두 번째 혹은 3번째 앞의 ALU instruction의 destination이라면 forwarding를 통해 data hazard를 해결 가능
- comparison register가 바로 전의 ALU instruction의 destination이거나 두 번째 앞의 load instruction의 destination인 경우 1 stall cycel이 필요
- add 명령어의 결과는 EX stage가 끝난 후에, load 명령어의 결과를 MEM stage가 끝난 후에 나옴
- branch 명령어의 경우 ID stage에서 comparison 결과를 알 수 있음. ID stage에서 branch 결과와 branch target address가 계산이 됨
- lw, add의 결과를 branch의 ID stage에서는 사용할 수 없기 때문에 1 cycle stall이 발생
- comparison register가 바로 앞의 load instruction의 destination인 경우 2 cycle stall이 발생
3. Dynamic Branch Prediction
- branch prediction buffer(branch history table): 기존의 branch 결과를 활용하기 때문에 이전의 branch 결과를 저장해주는 buffer가 필요
- index는 최근의 branch instruction addresses로 구성. 값으로 branch의 결과(taken/not taken)를 저장
- branch 명령어를 실행하면
- table를 확인한 후 이번 결과를 예측
- 예측한 결과에 따라 해당하는 명령어를 fetch해서 실행
- prediction 결과가 맞으면 계속 실행, 틀리면 pipeline을 flush하고 제대로 된 명령어를 실행
4.9 Exceptions
Exceptions and Interrupts
- exception: CPU 내부에서 발생하는 예상하지 못한 event (ex. overflow, systemcall ... )
- interrupt: 외부 장치에서 발생하는 예상하지 못한 event
- trap(software interrupt): 어떤 명령어를 사용할 경우 명령어가 interrupt를 발생시킴
- interrupt는 일반적으로 외부 장치에서 발생하지만 소프트웨어에서 발생하는 interrupt를 trap이라고 함
- syscall를 구현하는데 사용
- exception과 interrupt를 처리할 때 성능이 떨어질 수 밖에 없음
1. Handing Exceptions
- MIPS에서는 CP0(System Control Coprocessor)에서 exception를 관리
- exception이 발생하면
- 현재의 PC를 EPC(Exception Program Counter)에 저장
- Cause register에 exception 발생 원인을 저장
- 미리 지정한 메모리 주소(exception를 처리하기 위한 handler 주소가 저장되어 있음)로 jump
- exception 종류 상관없이 같은 메모리 주소로 jump
- Vectored Interrupts: handler 주소가 원인에 따라 다르게 정해짐
- 장점: jump된 메모리 주소에 따라 exception의 종류를 알 수 있음
- jump된 메모리 주소에서 바로 interrupt를 처리하는 경우와 메모리 주소에서 실제 handler로 한 번 더 이동한 후 interrupt를 처리하는 경우가 있음
Handler Actions
- 발생 원인을 파악하고 해당되는 handler로 jump
- cause register를 읽어서 왜 interrupt가 발생했는지 파악해야 함
- interrupt를 처리한 후 명령어를 다시 시작할 수 있으면 EPC를 사용해 원래 명령어로 돌아감
- 명령어를 다시 시작할 수 없는 경우 프로그램을 종료하고 에러 메시지를 저장
2. Exceptions in a Pipeline
- pipeline의 exception은 처리하기 힘듦. control hazard의 다른 형태이기 때문
- control hazard: 프로그램의 flow가 변경되어 hazard가 발생
- EX stage에서 add 명령어를 실행하는데 오버플로우가 발생하면 (add $1, $2, $3)
- 결과값이 $1 레지스터에 쓰여지는 것을 방지해야 함
- 이전의 명령어를 실행 완료해야하고 add 다음의 명령어는 flush해야 함
- Cause register와 EPC register를 setting
- handler로 jump
- branch에서 mispredict를 했을 경우와 처리 방법이 유사
Exception Properties
- Restartable exception
- pipeline를 flush하고 원래의 명령어로 돌아감
- EPC에 저장된 PC 값을 활용해서 다시 복원
- EPC에는 PC + 4의 값이 저장되어 있기 때문에 다시 PC에 값을 저장할 때는 4를 빼준 후 저장해줘야 함
3. Multiple Exceptions
- pipeline의 경우 한 번에 여러 명령어가 실행되기 때문에 exception도 여러 개가 발생할 수 있음
- 처리해주는 가장 간단한 방법은 pipeline의 가장 끝부분에 많이 실행된 명령어대로 처리하는 것
- 그 명령어 이전의 명령어는 모두 flush
- precise exception: 어떤 명령어를 먼저 처리할 것인지 규정되어 있는 것
- pipeline이 복잡한 경우
- 한 cycle마다 여러 명령어를 실행
- 실행 결과가 명령어 실행 순서와 바뀌는 경우 precise exception를 처리하기 힘듦
Imprecise Exception
- pipeline를 멈추고 현재 상태를 저장
- handler가 어떤 명령어에서 exception이 발생했는지 파악하고 어떤 명령어를 complete하고 flush할지 결정
- 하드웨어는 단순하지만 handler software는 복잡함
- 최신 cpu에서는 제공되지 않음
10주차 강의 끝!!!
게시물에 사용된 사진은 강의 내용을 캡쳐한 것입니다.