본문으로 건너뛰기
HMYHardware Wiki

HMY-Wiki

하드웨어 / CPU

파이프라인과 비순차 실행

명령 하나의 모든 단계를 끝낸 뒤 다음 명령을 시작하면, 실행 유닛은 대부분의 시간을 기다리며 보낸다. 파이프라인은 인출과 해독, 실행, 결과 처리를 여러 명령에 걸쳐 겹쳐서 단위 시간당 끝나는 명령 수를 늘린다. 다만 단계를 잘게 나눌수록 클럭을 올리기 쉬운 대신, 분기 예측이 틀렸을 때 버려야 할 작업도 늘어난다. 파이프라인이 깊다고 무조건 빠르지는 않은 이유다.

실행 구조

파이프라인
인출·해독·실행·결과 처리를 겹쳐 처리량을 높인다
비순차 실행
의존성이 없는 뒤쪽 명령을 먼저 처리한다
레지스터 이름 바꾸기
같은 레지스터 이름에서 생기는 가짜 의존성을 없앤다
리오더 버퍼
결과를 프로그램 순서대로 확정한다

비순차 실행(Out-of-Order Execution)은 앞선 명령이 데이터를 기다리는 동안, 의존성이 없는 뒤쪽 명령을 먼저 처리한다. 레지스터 이름 바꾸기는 서로 다른 명령이 같은 이름의 아키텍처 레지스터를 쓰면서 생기는 가짜 의존성을 없앤다. 예약 스테이션과 스케줄러는 입력이 준비된 동작을 실행 포트로 보낸다.

실행 순서가 달라져도 프로그램이 보는 결과는 원래 순서와 같아야 한다. 리오더 버퍼가 명령을 프로그램 순서대로 은퇴시키고, 예외가 생기면 정확한 지점의 상태를 복원한다. 메모리 연산은 로드·스토어 큐가 주소와 순서를 추적해 이 규칙을 지킨다. 이 장치들이 없으면 비순차 실행은 결과를 보장할 수 없다.

분기 예측과 추측 실행은 성능을 높이지만, 추측 과정에서 남은 캐시 상태가 정보 노출 통로가 되기도 한다. 이런 문제의 완화는 CPU 마이크로코드와 펌웨어, 운영체제, 프로그램이 함께 담당한다. 한쪽만 고쳐서 끝나는 문제가 아니다.

같은 클럭에서도 프런트엔드 폭과 실행 포트 수, 캐시, 예측 정확도, 메모리 의존성 처리 능력이 다르면 주기당 처리량이 달라진다. 흔히 인용하는 IPC 숫자는 특정 프로그램과 입력에서 관찰한 결과이며, 모든 작업에 고정된 CPU 속성이 아니다.

앞선 결과를 기다려야 하는 연산

앞 명령이 메모리에서 읽은 값을 다음 명령이 곧바로 사용한다면 실제 데이터 의존성은 남는다. 레지스터 이름 바꾸기는 같은 이름 때문에 생긴 의존성을 없애지만, 아직 계산되지 않은 값을 만들어 내지는 못한다. 비순차 실행이 대기를 가리려면 그동안 먼저 실행할 독립 명령이 있어야 한다.

분기 예측이 틀리면 잘못된 경로의 결과를 프로그램 상태로 확정하지 않고 올바른 경로에서 다시 시작한다. 따라서 반복문의 분기 패턴, 실행 중인 명령의 종류, 캐시 Miss가 모두 처리량에 영향을 준다. 파이프라인 단계 수 하나를 성능 순위로 읽을 수 없는 이유다.

상위 개념: CPU의 구조와 명령 실행 · 데이터 계층: CPU Cache

참고 링크