현대 CPU에서 Out-of-Order Execution(비순차 실행)은 명령어 간의 의존성을 극복하고 병렬 처리를 극대화하기 위한 핵심 기술입니다. 이 구조가 효과적으로 작동하기 위해서는 또 다른 중요한 기술, 바로 Register Renaming(레지스터 리네이밍)이 필요합니다. 레지스터 리네이밍은 명령어 간의 '가짜' 의존성을 제거함으로써 실행 순서를 유연하게 만들고, 성능을 극대화하는 데 기여합니다. 본 글에서는 Out-of-Order 실행 구조 내에서 Register Renaming이 어떤 역할을 하는지, 그리고 어떤 방식으로 구현되는지를 상세히 설명합니다.
명령어 의존성과 레지스터 충돌
CPU에서 여러 명령어를 동시에 처리하려면, 각 명령어가 사용하는 레지스터가 충돌하지 않아야 합니다. 그러나 실제 프로그램에는 다음과 같은 의존성(Dependency)이 존재합니다:
- RAW (Read After Write): 읽기 명령어가 이전 쓰기 명령어의 결과를 필요로 함
- WAR (Write After Read): 쓰기 명령어가 이전 읽기 명령어보다 먼저 실행되면 문제 발생
- WAW (Write After Write): 두 쓰기 명령어가 같은 레지스터에 기록하려 할 때 충돌 가능
이 중 RAW는 실제 데이터 의존성이고 반드시 지켜져야 하지만, WAR와 WAW는 이름 충돌(Name Dependency)에 불과합니다. 즉, 동일한 물리적 레지스터 이름을 사용하기 때문에 의존성이 생기는 것처럼 보이는 것입니다. 이 가짜 의존성을 제거해주는 기술이 바로 Register Renaming입니다.
Register Renaming의 원리와 구조
Register Renaming은 명령어가 사용하는 논리 레지스터(Logical Register)를 내부적으로 물리 레지스터(Physical Register)로 매핑하는 방식입니다. 이를 통해 서로 다른 명령어가 동일한 논리 레지스터를 사용하더라도, 실제로는 다른 물리 공간을 사용하게 됩니다.
이 매핑은 다음 두 가지 주요 구조를 기반으로 합니다:
- Rename Table: 각 논리 레지스터에 대응하는 현재 물리 레지스터를 추적
- Free List: 할당되지 않은 여유 물리 레지스터 목록
명령어가 디코딩될 때, 출력 레지스터는 새로운 물리 레지스터로 매핑되고, 이전 물리 레지스터는 이후에 반환됩니다. 이 과정을 통해 WAW, WAR와 같은 이름 의존성은 제거되고, 명령어 간 병렬 실행이 가능해집니다.
예를 들어, 다음과 같은 명령어들이 있다고 가정해봅시다:
1. ADD R1, R2, R3
2. SUB R1, R4, R5
순차 실행에서는 2번 명령어가 1번이 끝날 때까지 기다려야 하지만, Register Renaming을 통해 R1의 두 사용이 서로 다른 물리 레지스터로 매핑된다면 두 명령어는 병렬로 실행될 수 있습니다.
Out-of-Order 실행과의 통합 동작
Register Renaming은 Out-of-Order Execution 구조 내에서 매우 밀접하게 작동합니다. Out-of-Order 실행은 명령어를 프로그램 순서와 관계없이 가능한 순서대로 먼저 실행하는 방식이지만, 이를 위해서는 의존성 판단이 정확해야 합니다. 가짜 의존성까지 고려하면 실행 순서를 제한하게 되므로, Register Renaming을 통해 이러한 제약을 제거하는 것이 핵심입니다.
실제로 Out-of-Order 실행을 위한 파이프라인에서는 다음과 같은 단계가 포함됩니다:
- Issue: 명령어를 디코드 및 리네이밍하고 명령어 큐에 등록
- Dispatch: 실행 유닛에 보내기 전, 모든 오퍼랜드가 준비되었는지 확인
- Execute: 독립적인 명령어부터 순서에 상관없이 실행
- Write Back: 결과를 물리 레지스터에 기록
- Commit: 프로그램 순서에 맞춰 논리적 결과를 반영
이 과정에서 Register Renaming은 명령어 간 의존성 추적을 단순화하고, 명령어 병렬 실행률을 높여줍니다. 또한 실행 결과를 정렬하기 위한 Reorder Buffer(ROB)와 함께 사용되어, 프로그램의 논리적 일관성을 유지합니다.
결과적으로, Register Renaming은 Out-of-Order Execution이 제대로 작동하도록 만드는 필수 구성요소입니다. 이 기술이 없다면, 복잡한 명령어 흐름 속에서 의존성 판단이 어려워지고, 병렬 실행이 크게 제한됩니다.
현대 고성능 CPU에서는 수십~수백 개의 물리 레지스터를 활용한 리네이밍 시스템이 존재하며, 이를 통해 실질적인 연산 처리 속도를 극적으로 향상시키고 있습니다. Register Renaming은 사용자 입장에서는 보이지 않지만, 실제 성능 체감의 핵심 기술 중 하나로 작용하고 있습니다.