명령어를 순차적으로 실행하는 프로세서에 적용되는 기술로, 한 번에 하나의 명령어만 실행하는 것이 아니라 하나의 명령어가 실행되는 도중에 다른 명령어를 시작하는 식으로 여러 개의 명령어를 실행하는 기법이다.
순차적 처리에서는 12클럭이 필요하지만 파이프 라이닝을 적용하면 7클럭에 해결 가능하다.
파이프라이닝에 의한 속도 향상
파이프라인 단계 수를 k, 실행할 명령어 수 N, 각 파이프라인 단계가 한 클록 주기씩 걸린다고 하면.
즉 첫번째 명령어를 실행하는데 k 주기가 걸리고 나머지 N - 1개의 명령어 개수 만큼 한 주기씩 추가된다.
즉 명령어 N의 수가 무한히 증가하면 결국 k단계만큼 속도가 빨라진다.
해저드(harzard)
각 명령어의 처리시간이 일정하지 않고 처리 단계가 균등하지 않아서 문제가 발생하는 것을 해저드라고 한다.
구조적 해저드
자원 충돌: hw가 여러 명령들의 수행을 지원하지 않기 때문에 발생.
만약 한 명령어가 출력을 해야 하는데 다른 명령어가 이미 출력중이라면 한 사이클을 stall 한 이후에 출력을 실행해야 할 것이다.
해결 방법은 자원을 늘려주면 해결 가능하다. 하지만 파이프라인이 k 단계라면 최악의 경우에서 stall 없이 작동하려면 최대 k개의 명령어를 감당할 수 있어야 한다.
컨트롤 해저드
주로 분기문에 의해 발생한다. 분기문 조건의 실행이 완료 될 때까지 어느 분기로 이동할지 모르기 때문에 발생하는 해저드다.
위 사진에서 보듯이 분기문에 따라서 이전에 파이프라인에 들어가 있던 명령어들이 폐기될 수 있다. 이러면 파이프라이닝의 장점이 사라지게 된다.
명령어 재배치
1: if (z > 0) goto 4;
2: a = 1;
3: goto 5;
4: a = 0;
5: x = y + z; // 이 명령은 명령 1~4와 무관
위 분기분과 관련 관련 없는 5번 라인을 먼저 실행하는 것이다.
하지만 이 방법도 완벽히 stall을 제거할 수 없고 실제 프로그램 순서와 다르게 완료되므로 프로그래머에게 혼동을 줄 수 있다.
분기 예측
분기, 또는 분기하지 않는다고 가정하고 그에 따른 명령어를 예측에 기반해 실행한다. 즉 분기문의 결과를 미리 예측해서 파이프 라이닝을 진행한다. 만약 예측에 성공한다면 큰 성능 향상이 생기지만, 예측에 실패하면 파이프라이닝의 장점이 희석된다.
데이터 해저드
아직 파이프라인 명령어가 끝나지 않은 레지스터에 접근하여 명령어를 실행하려고 할 때
ADD 가 $2 + $3의 결과를 $1에 저장하기 전에, SUB 명령어로 $1 레지스터를 사용해 버린다. 결과 값이 저장되기 전에 레지스터를 읽으려고 하면 데이터 해저드(Data hazard) 가 발생한다. ( = 두개의 인접 명령어에 data dependency가 있다.)
freezing the pipeline(앞 명령어가 데이터를 write 할 때 까지 기다린다)
결국 stall이 발생하므로 클럭 손해가 발생한다.
전방 전달(forwarding)
write 하기 전, wirte할 내용이 계산되면 다음 명령어가 미리 받아온다.
위 사진에서 ADD의 EX단계에서 계산이 완료되면 다음 명령어인 SUB가 바로 데이터를 가져오면 된다.
슈퍼스칼라(super scalar)개념
하나의 명령어만을 수행하는 파이프라이닝과는 다르기 여러개의 명령어를 동시에 수행하는 것이다. 일반적인 파이프라이닝보다 수행시간에서 이득이 있다.
슈퍼스칼라(super scalar) 의존성
데이터 의존성: 첫번째 명령어 실행에서 변경되는 데이터를 두번째 명령어에서 사용하는 경우 실행순서가 바뀌면 안된다.
자원 의존성: 두 명령어가 같은 자원(예를 들어 나누기 연산 장치)를 사용할 경우 동시에 실행될 수 없다.
프로시저 의존성: 분기 명령어와 바로 다음 명령어는 같이 실행될 수 없다. 분기 명령어가 끝난 이후 다음 명령어가 실행돼야 한다.