ROB commit 폭: 완료된 C가 대기 중인 B를 앞지를 수 없는 이유
완료된 명령이 네 개 있고 코어가 한 사이클에 네 개를 commit할 수 있다면, 다음 사이클에 모두 확정될까. 숫자만으로는 답할 수 없다. ROB commit 폭은 처리 가능한 최대 개수지만, 실제로 확정할 수 있는 명령은 프로그램 순서의 가장 앞쪽에서 연속해 조건을 만족해야 한다.
뒤의 완료 비트가 앞의 대기를 건너뛰지는 못한다
가상의 ROB head 행에 프로그램 순서대로 A, B, C, D가 있다고 하자. 폭은 네 개이고 A와 C는 정상적으로 완료되었다. B는 아직 결과를 기다리고, D에는 예외가 기록되어 있다.
프로그램 순서: A B C D
현재 상태: 완료 대기 완료 예외
정상 commit: 가능 불가 불가 불가
A는 확정할 수 있다. 그러나 B가 아직 끝나지 않았으므로 C를 먼저 확정할 수는 없다. D의 예외도 앞의 B가 어떤 결과를 낼지 정해지기 전에 처리할 경계를 만들지 못한다. 완료 비트를 모두 세면 A와 C 두 개를 찾지만, 정상 확정 가능한 앞쪽 구간은 A 하나다.
B가 정상적으로 끝난 뒤에는 B와 C까지 정상 확정 가능한 구간이 된다. D는 정상 명령처럼 commit하지 않고, 가장 오래된 처리 대상이 되는 시점에 예외를 처리한다. 정확히 어느 클록에 trap 전환까지 수행하는지는 구현의 제어 규칙에 달렸지만, D를 뛰어넘어 더 젊은 명령의 상태를 먼저 노출할 수 없다는 경계는 같다.
BOOM 문서는 commit head의 명령이 더 이상 busy가 아니고 예외도 아닐 때 architectural state에 변경을 보이게 한다고 설명한다. 예외는 해당 명령이 head에 도달했을 때 처리하며, 그 뒤 상태를 버리고 확정 상태로 돌아간다. BOOM, The Commit Stage와 Exceptions and Flushes
여러 은행을 한 행으로 보는 이유
BOOM의 ROB는 W개의 bank를 갖는 원형 구조로 설명된다. 같은 fetch packet에서 보낸 최대 W개 명령을 서로 다른 bank의 같은 행에 넣는다. 이렇게 하면 행의 명령들이 공통된 주소 정보를 나누어 사용할 수 있어 저장 비용을 줄일 수 있다. 각 명령의 valid·busy·exception과 이름 변환 상태는 따로 남는다. BOOM, The ROB Organization와 ROB State
commit에서는 한 행의 조건을 함께 살펴 가능한 명령들을 확정한다. 앞의 A–D 예에서 네 bank를 병렬로 읽을 수 있다는 것은 네 명령을 어떤 순서로든 확정할 자유와 다르다. 먼저 걸리는 대기나 예외 이후의 명령은 아직 정상 commit 후보가 아니다. 유효하지 않은 빈 슬롯은 실제 명령이 아니므로, busy인 유효 명령과 같은 이유로 순서를 막는다고 해석해서도 안 된다.
폭을 넓히면 완료 조건 검사뿐 아니라 목적지 상태 갱신, 이전 물리 번호 반환과 store의 확정 알림도 여러 개 처리해야 한다. BOOM은 commit된 store의 개수를 LSU에 알리고, LSU가 그 store들을 메모리로 보내는 과정을 별도로 설명한다. 네 store를 commit했다는 사실이 네 개를 같은 사이클에 메모리로 내보냈다는 뜻은 아니다.
행의 빈칸도 최대 폭과 평균을 갈라놓는다
해당 BOOM 문서는 현재의 commit이 여러 행을 가로질러 후보를 찾지는 않는다고 명시한다. head 행에 정상 완료된 명령이 적으면, 다음 행에 후보가 더 있어도 최대 폭을 채우지 못할 수 있다. 분기가 있는 코드에서는 행에 빈칸이 남을 수 있다는 설명도 함께 나온다.
가령 폭이 4인 가상 ROB에서 네 행에 각각 유효 명령 세 개씩만 있고, 모두 정상 완료되었다고 하자. 행을 가로지르지 않으며 다른 제한이 없다면 12개를 처리하는 데 네 번의 commit 기회가 필요하다. 평균은 사이클당 세 개다. 같은 12개가 빈칸 없는 세 행에 들어 있었다면 세 번에 처리할 수 있다.
이 계산은 폭 4가 잘못된 설계라는 주장이 아니다. 명령 배치와 행 단위 선택이 평균 처리량에 영향을 준다는 예다. 여러 행을 합쳐 고를 수 있는 다른 설계는 빈칸의 손해를 줄일 수 있지만, 주소 정보와 상태 갱신을 여러 행에 걸쳐 연결하는 제어 비용을 고려해야 한다. BOOM의 행 방식이 주는 저장 이점과 commit 활용률의 제약을 함께 보아야 한다.
완료를 빨리 만드는 것과 확정을 넓히는 것
처음 예에서 B의 결과가 늦는 한 commit 폭을 4에서 8로 늘려도 B 뒤를 넘어설 수 없다. 실행 쪽에서 오래된 B를 더 빨리 완료하는 변화가 더 직접적인 효과를 낼 수 있다. 반대로 오래된 명령이 항상 준비되어 있고 head 행도 잘 채워진 상황이라면, 좁은 commit 폭이 지속적인 병목이 된다.
따라서 실제 병목을 보려면 몇 개가 끝났는지와 몇 개가 확정되었는지, 왜 그 사이에 대기가 생겼는지 나누어 확인해야 한다. 오래된 명령의 미완료, 예외 처리, 행의 빈칸과 commit 자원 부족은 같은 낮은 평균을 만들 수 있지만 해결 방법은 다르다.
ROB commit 폭이 의미하는 것은 조건이 맞을 때 한 번에 확정할 수 있는 최대량이다. A와 C가 완료되어도 B 때문에 A만 나가는 예에서 그 조건이 보인다. 앞쪽 확정 경계를 지키고, 행의 배치와 후속 자원의 수락까지 연결해야 넓은 폭이 프로그램의 유용한 처리량으로 바뀐다.