Pipelined Instruction 수행시 발생할 수 있는 Hazard 의 종류
- Sturcuctural Hazard
- Data Hazard
- Freezing the pipeline
- Forwarding
- Compiler Scheduling
- Control Hazard
- Optimized branch processing
- Branch prediction
- Delayed branch
1) Structural Hazard
: 동일 자원(Resouce : Memory or register)에 대해 pipelined 된 다중 instruction이 동시에 접근하는 문제
(기본적으로 하나의 자원에는 하나의 instruction 만이 접근하여 사용할 수 있다.)
즉, 동일 Cycle에 서로 다른 instruction 에서 동일 resource 를 접근할 때 발생한다.
Solution 1)
메모리의 경우 별도의 cache(Instruction cache, Data cache)를 두어 동시에 처리될 수 있게 한다.
Instruction cache : Instruction을 가져오기(fetch)위해 memory 에 접근하는 경우 사용 Data cache : 연산을 위해 data 를 memory 에서 load하거나 store 하는 경우 사용
|
한 cycle 을 추가로 나누어 나우어진 각각의 시간에 따로 접근하여 자원을 동시 사용하지 않도록 한다.
Solution 2)
Time-multiplexed 를 지원한다. 한 cycle을 반으로 나누어 절반에서는 read 를 지원하고 나머지 절반에서는 write를 지원하도록 한다.
Solution 3)
Multi-port register file 을 제공한다. Multi-port register file 이란 한 Cycle에 두개의 read 와 하나의 register를 지원하는 register를 뜻한다.
2) Data Hazard
한 instruction 의 결과를 pipelining 된 바로 다음 instruction 에서 사용해야 하는 상황이지만 계산 값이 나오기 전이라 해당 값(data) 사용이 불가능한 문제
예)
ADD $1, $2, $3
ADD $7, $8, $1
Solution 1) Freezing the pipeline
앞선 instruction 의 결과가 나올 때 까지 다음 instruction 의 실행을 미루는 것을 의미한다.
즉, instruction 가져오는 것(IF : Instruction Fetch)을 대기한다.
Solution 2) Internal Forwarding
Solution 1)과는 달리 다음 instruction 은 cycle에 맞게 가져오고 앞선 instruction의 계산 값이 나오는 즉시 다음 instruction 이 사용할 수 있도록 값을 넘겨준다.
Solution 3) Compiler scheduling
결과 값과 무관한 instruction 을 해당 instruction들 사이에 수행시킴으로써 별다른 대기나 조치 없이 계산된 값을 인자값으로 사용할 수 있도록 한다.
3) Control Hazard
Branch, Jump 혹은 Call/Return 과 같이 상황에 따라 다음 instruction 이 바뀌어 다음에 처리해야 하는 instruction 을 판단하기 어려운 문제
Solution 1) Optimized branch processing
branch 의 조건을 확인하고 다음 instruction 을 fetch 하면 비용이 크다.
이에 branch 조건을 간략화시키고, 별도의 HW를 통해 branch/jump target address를 미리 계산해 둔다.
위 내용을 기반으로 기존 5 cycle 을 2 cycle로 줄이는게 목표로 한다.
Solution 2) Branch prediction
Predict-not-taken
다음 Instruction 이 실행될 것이라 예상하고, 실제 결과와 상관없이 다음 instruction을 pipelining 하는 것이다.
실제로 not-taken 일 경우 예측이 맞은 것이므로 별도의 penalty 없이 다음 instruction 수행이 가능하다.
반면 실제 판단 결과 다른 instruction이 수행되어야 한다면 불필요하게 실행한 instruction 은 nop (state를 못바꾸게 함) 으로 처리해 버리고 처리되어야 할 instruction 을 수행한다.
Solution 3) Delayed branch
일반적으로 어떤 scheme 을 사용하더라도 원래 instruction의 semantic을 바꾸면 안된다.
(즉, sequential instruction 처리와 같이 처리가 되어야 함)
하지만 branch instruction의 semantic 을 바꿈. (최근에는 더 좋은 prediction 방식들이 나와서 사용되지 않는다.)
branch 가 오면 바로 조건 만족과 무관하게 다음 instruction을 무조건 실행. (일반적으로는 실행하면 안됨)
이후 조건이 만족하지 않으면 계속 그 다음 instruction을 수행하고, 만족하면 해당 instruction 으로 이동하여 수행.
(어떤 조건이든 branch instruction 의 다음 instruction을 실행함)
이에 따라 branch 문 앞에서 수행되어야 하는 instruction을 branch 문 뒤로 이동하여 수행하여 처리하고자 한다.
만약 앞에 수행되어야 하는 instruction 이 모두 의존적인 경우 branch instruction의 target 에 있는 instruction 을 가져와 수행한다. (만약 branch 가 taken이 되지 않으면 nop 처리)