```
▣ 프로그램 수행 향상 방법
1) CPI (Clock Per Instruction)의 감소
- 파이프라인, 슈퍼스칼라, 파이프라인드 슈퍼스칼라, VLIW 통한 병행성/병렬성 향상
2) 명령어 수 감소
- 내부 아키텍처 특성 고려한 프로그래밍, 고성능 컴파일러 이용 최적화
3) Clock cycle time 감소
- Clock rate 상승, 오버클럭킹
▣ 파이프라인의 개념
- 명령어를 실행하는데 사용되는 하드웨어를 여러 개의 독립적인 단계들로 분할하고, 그들로 하여금 동시에 서로 다른 명령어들을 처리하도록 함으로써 CPU의 성능을 높여주는 기술
▣ 명령어 수행과정
1) FI(Fetch) 인출
- 명령어를 기억장치로부터 인출
2) DI(Decode) 해독
- 인출된 명령어를 해석
3) EI(Execute) 실행
- 해석된 결과를 수행
4) WB(Write Back) 저장
- 수행된 결과를 저장
▣ 명령어 병렬화 기법
1) 단일 Pipeline (단일중첩)
- 명령어 수행과정에서 각 단계를 한번만 중첩
- 다수의 동작을 동시에 수행하는 병렬처리 기술
2) Super Pipeline (엇갈림)
- 하드웨어 장치의 연속 사용 위해, 몇 가지 동작을 명령 수행과정에서 각 단계에 엇갈리게 중첩하는 기술
3) Super Scalar (2중 중첩)
- 프로세서 내에 Pipeline 된 ALU를 여러 개 포함.
- 매 사이클마다 다수의 명령어들이 동시에 실행하는 병렬처리 기술
4) Super Pipelined Super Scalar (2중 중첩 엇갈림)
- 슈퍼스칼라 기법에 슈퍼 파이프라이닝 기법 적용
5) VLIW (Very Long Instruction Word)
- 동시에 수행될 수 있는 명령어들을 컴파일러 수준에서 추출, 하나의 명령어로 압축, 수행하는 병렬처리 기술
▣ 처리속도향상
= (순차실행시간/파이프라인 소요시간)
= n*k/(n+(k-1))
(n : 명령어수, k : 파이프라인 단계 수)
▣ 파이프라인 효율성 저하 원인, 해저드의 개념
- 구조적 해저드
- 데이터 해저드
- 제어 해저드
▣ 구조적 해저드
1) 개념
- 하드웨어적 제한으로 인해 동일 클럭사이클에 명령어들을 병렬적으로 수행하지 못하여 발생하는 해저드
2) 원인
- 각각의 다른 명령어가 동일 메모리, 동일 레지스터, ALU 등을 동시에 접근하려 할 때 후속 명령어가 지연됨
▣ 데이터 해저드 개념
1) RAR (Read After Read)
- R1 ← "R2" + R3
- R4 ← "R2" + R5
= 해저드 발생하지 않음
2) RAW(Read After Write)
- "R1" ← R2 + R3
- R5 ← "R1" + R4
= True 해저드, 연산 결과, 연산 결과보다도 Read 필요시간이 빠름. 파이프라인, 슈퍼스칼라 구조에서 발생. Forwarding(Bypassing)으로 해결
3) WAR(Write After Read)
- R3 ← "R1" + R2
- "R1" ← R4 + R5
= False 해저드, 실제 Static 형태의 파이프라인 구조에서는 발생하지 않는 형태이나, Dynamic 형태의 Pipeline의 경우 명령어 순서가 바뀌면서 Dependency 발생 할 수 있음. Register Renaming 으로 해결
4) WAW(Write After Write)
- "R1" ← R2 + R3
- "R1" ← R4 + R5
= True 해저드, 동일한 레지스터에 쓰기를 시도하는 경우 발생, 파이프라인 구조에서는 발생하지 않으나 슈퍼스칼라 구조의 다중 파이프라인 구조에서 발생. Renaming으로 해결하거나, Temporary Register 사용으로 회피 가능.
▣ 제어 해저드
1) 개념
- 명령어의 실행 순서를 변경하는 명령어들 (Branch, Jump)에 의해 발생되는 해저드
2) 개념도
- Instruction i : IF, D, EX, M W
- Instruction i+1 : IF, stall, stall, IF, D, EX, M, W
- Instruction i+2 : stall, stall, stall, IF, D, EX, M, W
3) 사례
- beq rs, rt, label : 래지스터 rs와 rt가 같으면 변위에 의해 지정된 명령어 만큼 조건 분기함. rs와 rt가 동일한지 비교하고, 분기할 경우 직후의 명령어는 stall이 발생하고, 분기하지 않을 경우 그대로 수행함
▣ 구조적 해저드 해결방안
1) Adder 추가
- Instruction Fetch 단계의 PC값 증가는 간단한 ALU내의 Adder가 아닌 별도의 Adder 추가를 통해 해결
2) Memory 추가
- Instruction Fetch 단계와 Memory Access 단계의 메모리 접근 충돌은 별도의 Cache 메모리를 두어 해결
- Instruction/Data용 L1 Cache와 전용 버스를 통한 해결
3) 레지스터 사용
- Instruction Decode와 Write Back 단계의 레지스터 접근 충돌은 시분할 Read/Write접근, 또는 멀티 포트 레지스터 사용으로 해결
4) 전용 연산기 추가
- 곱셈기, 나눗셈기, Barrel Shifter 등 ALU에서 다수의 작업이 필요한 연산에 대해 별도의 연산장치 추가를 통한 해결
= 근본적인 방법은 Resource의 제약사항 극복을 위한 추가적인 HW 및 버스확장 등 으로 해결
▣ 데이터 해저드 해결방안
1) Bypassing (Forwarding)
- ALU의 출력에 MUX를 추가하여 출력값을 그대로 다음 파이프라인의 ALU연산 입력으로 사용하도록 Bypassing 시킴
2) 명령어 재배치 (컴파일러)
- 프로그램의 전체적인 명령어의 순서에 상관이 없으나, Data Dependency가 존재할 경우 실행 순서를 변경시킴
3) Register Renaming
- 사용하는 레지스터의 이름을 변경하여 데이터 의존성 해결
4) Interlocking/NOP
- 인위적으로 Rollback을 하거나 파이프라인 중단을 막기 위해 하위 파이프라인 실행을 중단시키거나, NOP(No Operation) 명령어를 추가하여 해저드를 회피함
▣ 제어 해저드 해결방안
1) Predict-Not-Taken
- Branch 명령어 뒤에 Delay Slot을 추가하여 무조건 실행함
- Branch 가 발생하지 않을 경우 파이프라인 실행 손실 없음
- Branch 가 실행될 경우 Delay Slot의 Flush 발생
2) Branch Target Buffer
- 분기 예측의 과거 History에 따라 결정
- 2bit 이력에 기반한 분기 예측
- 4개의 상태를 유지해서 다음의 성공확률을 높이려고 시도
3) Software Pipelining
- for/while 구문에 효과적임
- 반복적으로 수행하는 명령어들을 풀어서 수행함
```