in-flight instruction window: 여덟 칸을 채워도 실행 장치가 쉴 때
프로세서가 더 많은 명령을 동시에 붙잡고 있으면 느린 메모리 접근을 더 잘 숨길 수 있을 것 같다. 그런데 그 공간을 늘렸는데도 실행 장치가 쉬는 시간이 그대로인 경우가 있다. in-flight instruction window의 크기는 볼 수 있는 작업의 범위를 넓힌다. 그 범위 안에 지금 실행할 수 있는 작업이 있는지는 별도의 문제다.
기다리는 명령 뒤를 얼마나 볼 수 있는가
비순차 실행 코어는 앞의 명령이 끝나지 않아도 뒤쪽의 독립적인 명령을 실행할 수 있다. 동시에 들어와 아직 확정되지 않은 명령을 in-flight라고 부른다. BOOM의 ROB는 이 명령들을 프로그램 순서로 추적하고, 가장 오래된 명령이 준비되었을 때부터 commit한다. 뒤의 명령이 먼저 완료될 수 있지만 앞의 확정 경계를 넘어 버릴 수는 없다. BOOM, The ROB Organization와 The Commit Stage
따라서 오래된 load 하나가 기다리면, 뒤쪽 명령들이 완료되어도 공간을 계속 차지할 수 있다. 창이 가득 차면 그보다 더 뒤에 있는 유용한 독립 명령을 새로 가져오는 데 제한이 생긴다. 큰 창이 지연을 숨기는 데 도움이 되는 이유는 느린 명령을 빠르게 만드는 것보다, 그동안 처리할 다른 일을 더 멀리서 찾는 데 있다.
네 칸과 여덟 칸을 같은 조건에서 비교하면
가상의 창은 가장 오래된 load L을 포함해 최대 네 명령을 담는다고 하자. L은 앞으로 8사이클 동안 기다린다. 뒤의 명령은 모두 L과 무관한 정수 계산이고, 입력이 준비되어 있으며 한 사이클에 두 개씩 실행할 수 있다고 가정한다. 설명 시작 시점에 창은 이미 가득 차 있다.
네 칸이라면 L 뒤에서 실행할 수 있는 명령은 세 개다. 첫 사이클에 두 개, 다음 사이클에 한 개를 보내면 그 범위의 일은 끝난다. 그래도 L이 완료되지 않았으므로 이 예의 뒤쪽 명령은 아직 확정되지 않았고, 창이 비워지지 않는다.
같은 조건에서 여덟 칸이라면 L 뒤의 독립 명령 일곱 개를 볼 수 있다. 두 개씩 세 번, 마지막 한 개를 보내면 네 번의 선택으로 일곱 개를 처리한다. 네 칸보다 대기 중에 더 많은 계산을 끝낼 수 있지만, 두 명령씩 실행하는 포트가 갑자기 네 명령씩 처리하는 것은 아니다. L 자체의 8사이클도 그대로다.
이 예는 최대 수용량과 독립 작업 수의 관계를 분리한 모델이다. 실제 코어의 fetch·dispatch 속도나 load 응답, 연산 지연을 재현한 성능 측정은 아니다. 시작부터 가득 찬 창이라는 가정도 명시한 이유가 있다. 실제로 명령을 채우는 시간이 길면 큰 공간의 효과가 그만큼 늦게 나타난다.
창 전체가 한 결과를 기다리면 다른 답이 나온다
뒤의 일곱 명령이 모두 앞 명령의 결과에 의존하는 사슬이라면 어떨까.
A1 = load 결과 + 1
A2 = A1 + 1
A3 = A2 + 1
...
이제 L이 끝나기 전에는 A1부터 준비되지 않는다. 여덟 칸을 모두 채워도 대기 중 실행할 독립 작업이 없다. L이 끝난 뒤에도 각 연산의 결과가 다음 연산에 도착해야 한다. 설명용으로 그 간격을 한 사이클이라고 두면, 두 개를 보내는 포트가 있어도 한 사슬을 매 사이클 두 단계씩 진행할 수는 없다.
BOOM의 issue queue 역시 모든 입력이 준비된 명령만 실행 요청을 내고, 포트가 지원하는 연산을 선택한다. 더 많은 명령을 보관하는 일은 준비되지 않은 입력을 준비된 값으로 바꾸지 않는다. BOOM, Issue Slot와 Issue Select Logic
공간의 크기와 공간에 머무는 시간을 곱해 본다
창이 필요한 규모는 명령의 체류 시간에도 영향을 받는다. 취소 없이 명령이 들어와 확정되는 정상상태의 간단한 수지를 생각해 보자. 매 사이클 평균 두 명령이 들어오고, 각 명령이 들어온 뒤 확정되어 떠날 때까지 평균 20사이클 머문다면 평균 점유량은 40명령이다. 오랜 관찰 구간에서 각 명령이 차지한 시간들을 합해 구간 길이로 나눈 결과다.
이 관계는 40칸이면 모든 순간의 정지가 사라진다는 보장이 아니다. 평균보다 큰 순간 점유량이 있고, 오래된 한 명령이 막히면 뒤의 체류 시간이 늘어난다. 공간이 부족해서 이미 평균 유입량을 줄였다면 처음 가정한 사이클당 두 명령을 유지할 수도 없다. 평균 처리율과 체류 시간은 설계의 수지를 확인하는 기준이다.
ROB만 키워도 다른 자원이 먼저 찰 수 있다. 목적지 물리 레지스터, 아직 실행하지 않은 명령의 issue 슬롯, 메모리 요청을 추적하는 공간은 서로 다른 시점에 배정되고 반환된다. 이 중 어느 제한에 먼저 도달하는지에 따라 ROB의 남은 칸이 실효적인 창 확장으로 이어지지 않을 수 있다. BOOM도 ROB와 별도로 issue queue와 rename의 자원 관리를 구분한다. BOOM, The Free List
큰 창에 들어온 작업 중 잘못 예측한 경로의 명령이 많다면 실행 활동은 늘어도 확정되는 유용한 명령은 늘지 않을 수 있다. 소비 전력과 복구할 상태도 함께 고려해야 한다. 내부에 명령이 많이 있다는 숫자만으로 프로그램이 빨리 끝난다고 판단할 수 없는 이유다.
in-flight instruction window를 넓히는 효과는 기다리는 구간 뒤에 독립적인 일을 발견할 수 있을 때 나타난다. 네 칸의 세 명령과 여덟 칸의 일곱 명령을 비교한 예는 그 가능성을 보여 준다. 같은 공간을 의존 사슬로 채우면 답은 달라진다. 지연, 독립성, 실행 포트와 다른 저장 자원을 함께 보아야 큰 창의 비용이 실제 처리량으로 돌아오는지 알 수 있다.