핵심 인사이트 (3줄 요약)
- 본질: WAW (Write After Write)는 선행 명령어가 결과값을 쓰기도(Write) 전에 후행 명령어가 해당 위치에 먼저 값을 써버려(Write), 최종적으로 남아야 할 최신 데이터가 구형 데이터에 의해 덮어씌워지는 출력 의존성 (Output Dependency) 상황이다.
- 가치: 명령어마다 실행 시간이 다른 다중 파이프라인(예: 정수 1클럭, 부동소수점 10클럭)이나 비순차 실행 (Out-of-Order Execution) 환경에서 데이터 무결성을 파괴하는 고질적인 병목이 된다.
- 판단 포인트: 데이터 인과관계가 아닌 '이름(공간)'이 겹쳐서 발생하는 가짜 의존성이므로, **레지스터 리네이밍 (Register Renaming)**과 **리오더 버퍼 (ROB)**를 통해 실행 순서와 기록 순서를 분리하여 완벽하게 해결한다.
Ⅰ. 개요 및 필요성
WAW 해저드는 "느린 앞사람이 늦게 제출한 답안지가, 빠른 뒷사람이 미리 제출한 최신 답안지를 덮어버리는" 사고다. 기본 5단 파이프라인에서는 모든 명령어가 순서대로 WB(쓰기) 단계를 밟으므로 발생하지 않으나, 성능을 위해 여러 개의 파이프라인을 동시에 가동하고 순서를 뒤섞기 시작하면서 치명적인 데이터 오염원으로 부상했다.
이 해저드를 관리해야 하는 이유는 아키텍처 상태 (Architectural State)의 일관성 보장 때문이다. 프로그램은 나중에 나온 명령어가 최종적으로 값을 결정할 것을 기대한다. 하지만 실행 속도 차이로 인해 이 순서가 뒤집히는 것을 방치하면, 시스템은 영원히 잘못된 옛날 값을 최신 값으로 오해하고 연산을 이어가게 된다. 따라서 하드웨어가 명령어를 '실행'하는 순서는 뒤섞더라도, 최종 '결과 기록'만큼은 철저히 프로그램 순서를 지키게 만드는 정교한 통제 기작이 필수적이다.
- 📢 섹션 요약 비유: 페인트공 1번이 빨간색을 칠하려 조색하는 동안(느린 연산), 성격 급한 2번이 파란색을 먼저 칠해버렸는데(빠른 연산), 뒤늦게 1번이 빨간색을 그 위에 덧칠해버려 최종적으로 남아야 할 파란색이 지워지는 사고와 같습니다.
Ⅱ. 아키텍처 및 핵심 원리
WAW 해저드는 파이프라인의 길이가 서로 다른 명령어들이 여러 개 섞여 돌아갈 때 발생한다.
| 명령어 순서 | 어셈블리 예시 | 연산 소요 시간 | 설명 |
|---|---|---|---|
| 명령어 1 (선행) | DIV $t1, $t2, $t3 | 10 클럭 (느림) | $t1에 한참 뒤에 씀 |
| 명령어 2 (후행) | ADD $t1, $t4, $t5 | 1 클럭 (빠름) | $t1에 순서를 앞질러 씀 |
┌─────────────────────────────────────────────────────────────────────────────┐
│ 다중 파이프라인 환경에서의 WAW 발생 메커니즘 시각화 │
├─────────────────────────────────────────────────────────────────────────────┤
│ [ 시간축(T) ] T+1 T+2 T+3 ... T+10 │
│ Inst 1(DIV): [ EX1 ]─▶[ EX2 ]─▶[ EX3 ]───(진행 중)──▶[ WB ] (t1=DIV값) │
│ Inst 2(ADD): [ EX ] ─▶[ WB ] (t1=ADD값) │
│ │
│ * 논리적 결과: 최종 t1에는 ADD의 결과가 남아야 함. │
│ * 실제 현상: ADD가 먼저 쓰고 나간 자리를 늦게 끝난 DIV가 덮어써버림! │
│ * 결과: 프로그램이 끝난 후 t1에 엉뚱한 옛날(DIV) 값이 남아있음 (WAW 사고) │
└─────────────────────────────────────────────────────────────────────────────┘
여기서도 핵심은 두 명령어 사이에 데이터가 오가는 관계가 전혀 없다는 것이다. 단순히 $t1이라는 이름의 상자가 출력용으로 필요했을 뿐이다. 그래서 이를 가짜 의존성 (False Dependency) 또는 **출력 의존성 (Output Dependency)**이라고 부른다.
- 📢 섹션 요약 비유: 어제 출발한 일반 우편(DIV)과 오늘 출발한 특급 택배(ADD)가 있을 때, 특급 택배가 먼저 도착했는데 다음 날 도착한 일반 우편이 우편함(레지스터)의 특급 택배를 밀어내고 자리를 차지해버려 수취인이 옛날 물건을 받게 되는 꼴입니다.
Ⅲ. 비교 및 연결
WAW는 앞서 살펴본 WAR와 형제 격인 해저드지만, 보호해야 할 대상이 다르다.
| 비교 항목 | WAR (반의존성) | WAW (출력 의존성) | 아키텍처적 통찰 |
|---|---|---|---|
| 타이밍 역전 | 뒤가 너무 일찍 써버림 | 뒤가 너무 일찍 써버림 | (동일) |
| 피해 상황 | 앞이 잘못된 값을 읽음 | 최종값이 옛날 걸로 남음 | 과정 오염 vs 결과 오염 |
| 보존 대상 | 앞의 입력 데이터 | 뒤의 출력 데이터 | 인풋 보호 vs 아웃풋 보호 |
| 해결 기법 | 레지스터 리네이밍 | 리네이밍 + ROB 정렬 | 이름 세탁 + 퇴근 정렬 |
현대 CPU는 레지스터 리네이밍으로 $t1 간판을 서로 다른 물리 공간(P1, P10)으로 분리하여 충돌을 막고, **리오더 버퍼 (ROB)**를 통해 "비록 P5가 늦게 완료됐어도 프로그램 순서상 P10이 나중 것이니 P10만 최종 합격!"이라고 판정하는 정렬 과정을 거친다.
- 📢 섹션 요약 비유: WAR는 "형이 밥 먹는 그릇에 동생이 반찬 담겠다"고 싸우는 것이고, WAW는 "누가 최종적으로 그릇을 차지할지" 싸우는 것입니다. 그릇을 따로 주고(리네이밍) 나중에 엄마(ROB)가 순서를 정해주면 해결됩니다.
Ⅳ. 실무 적용 및 기술사 판단
실무 아키텍트에게 WAW 해결은 '은퇴 (Retirement)' 단계의 정교한 설계로 귀결된다.
설계 및 실무 판단 포인트
- 커밋 (Commit)의 순차성: 하드웨어가 명령어를 아무리 미친 듯이 섞어서 실행하더라도, 실제 아키텍처 상태(레지스터 값, 메모리)에 반영할 때는 반드시 프로그램에 적힌 원래 순서대로 한 줄씩 은퇴시켜야 한다. 이것이 ROB의 절대 원칙이다.
- 정밀한 예외 처리 (Precise Exception): WAW를 해결해두면, 중간에 예외(Error)가 터졌을 때 "딱 여기까지 실행했고, 최종값은 이놈이다"라고 정확히 롤백(Roll-back)할 수 있다. 순서가 꼬여있으면 복구가 불가능하다.
- PPA와 ROB 크기: WAW를 완벽히 감추려면 수십~수백 개의 완료된 명령어를 담아둘 거대한 리오더 버퍼가 필요하다. 이는 칩 면적을 많이 차지하므로, 성능과 비용 사이의 최적의 깊이를 결정해야 한다.
안티패턴
-
무분별한 누적 변수 사용:
sum = sum + a; sum = sum + b;처럼 하나의 변수에 값을 계속 덮어쓰는 코드는 WAW를 무한 생성한다. 컴파일러가 최선을 다해 풀어주지만, 개발자가 변수 이름을 넉넉히 쓰는 것이 하드웨어 리네이밍의 부담을 덜어주는 좋은 코딩이다. -
📢 섹션 요약 비유: 카페에서 모든 손님에게 "1번 진동벨" 하나만 주면 커피가 나올 때 누구 건지 다 섞여버립니다(WAW). 손님마다 개별 진동벨(리네이밍)을 주고, 나오는 순서대로 일단 선반에 둔 뒤(ROB), 손님이 온 순서대로 커피를 건네줘야(커밋) 사고가 안 납니다.
Ⅴ. 기대효과 및 결론
WAW 해저드는 **'가상 공간'**과 **'시간 재정렬'**을 통해 정복된 기술적 장애물이다.
결론적으로 현대 아키텍처는 WAW라는 물리적 제약을 레지스터 리네이밍과 ROB로 완벽하게 은닉함으로써, 파이프라인의 길이가 제각각인 수많은 특수 연산기(AI 가속기, FPU 등)를 병렬로 마구 돌릴 수 있는 자유를 얻었다. 미래에는 물리 레지스터 용량을 무한정 늘리는 대신, 더 이상 필요 없는 결과값을 빛의 속도로 지워버리는 적응형 자원 회수 기술이 발전하며 전력 효율의 신기원을 열 것이다.
- 📢 섹션 요약 비유: WAW는 좁은 주차장에 차들이 엉키는 사고였지만, 지하 주차장(PRF)을 파고 발렛 파킹(리네이밍)을 거쳐 나갈 때 다시 줄을 세워주는(ROB) 초정밀 관리 시스템 덕분에 완전히 사라졌습니다.
📌 관련 개념 맵
| 개념 | 연결 포인트 |
|---|---|
| 리오더 버퍼 (ROB) | 비순차 실행 결과들을 원래 순서로 줄 세워 WAW를 막는 최종 수문장 |
| 출력 의존성 (Output) | 데이터의 인과관계가 아닌 쓰기 결과의 선후 관계를 뜻하는 WAW의 본질 |
| 은퇴 (Retirement) | 연산이 완료된 명령어를 확정 짓고 레지스터 상태를 업데이트하는 단계 |
| 레지스터 리네이밍 | 이름이 겹치는 두 쓰기 명령을 물리적으로 찢어놓는 기술 |
👶 어린이를 위한 3줄 비유 설명
- 1번 친구가 아주 큰 그림을 도화지에 그리고 있었는데, 2번 친구가 그 옆에 작은 낙서를 순식간에 휘리릭 그렸어요.
- 그런데 1번 친구가 뒤늦게 큰 그림을 다 그리고는 "내 그림이 최고야!"라며 도화지 전체를 덮어버려서 2번 친구의 최신 낙서가 지워져 버렸죠.
- 이렇게 순서가 뒤바뀌어 최신 정답이 지워지는 걸 'WAW 해저드'라고 해요. 선생님(CPU)은 이걸 막으려고 친구들에게 각자 다른 도화지를 준답니다!