모든 이야기

bypass network: 덧셈 결과가 저장 경로를 기다리지 않는 법

덧셈 결과를 다음 덧셈이 바로 사용한다고 하자. 첫 결과를 레지스터 파일에 저장하고, 다음 명령이 그 값을 다시 읽을 때까지 기다리면 계산 자체보다 결과의 왕복 경로가 길어질 수 있다. bypass network는 생산자의 결과를 소비자의 입력으로 직접 전달해 이 간격을 줄인다. 다만 전달할 값이 있다는 사실과, 정확한 시점에 정확한 소비자에게 줄 수 있다는 사실은 다르다.

저장 경로보다 먼저 도착하는 길

가상의 두 연산을 물리 레지스터 번호로 써 보자.

P: p20 = 3 + 4
C: p21 = p20 + 1

P가 만든 7을 C가 사용하면 결과는 8이다. 설명을 위해 P의 결과가 사이클 1에는 직접 전달 가능하고, 레지스터 파일의 정상 읽기 경로에서는 사이클 2에 새 값이 보인다고 가정한다. 이는 특정 RTL의 클록 경계나 실제 BOOM의 전체 지연을 지정한 것이 아니라, 두 경로의 도착 차이를 정한 모델이다.

직접 경로가 없다면 C는 사이클 2의 읽기까지 기다린다. 직접 경로가 있고 C의 입력 선택 시점에 7이 도착한다면 사이클 1부터 계산을 시작할 수 있다. 이 모델에서는 시작이 한 사이클 당겨진다. 여러 명령이 같은 RAW 의존으로 이어져 있다면 이런 간격이 반복되어 긴 차이를 만들 수 있다.

BOOM의 원문은 ALU 결과를 Register Read 단계의 끝에서 전달해 연속된 ALU 연산을 issue할 수 있다고 설명한다. 결과를 저장하는 과정 자체를 없애는 것이 아니라, 소비자가 저장 후 읽기만을 유일한 경로로 사용하지 않게 하는 것이다. BOOM, Bypass Network

값뿐 아니라 어느 버전의 값인지도 전달한다

여러 생산자가 동시에 결과를 내면 소비자 입력에는 선택 회로가 필요하다. 소비자의 소스 번호와 생산자의 목적지 번호를 비교하고, 유효한 결과 중 맞는 값을 고른다. 물리 레지스터를 사용하는 설계에서는 논리 이름만 비교해서는 부족하다.

예를 들어 P는 x5의 이전 버전인 p20을 만들고, 더 젊은 Q는 같은 x5의 새 버전인 p22를 만든다고 하자. C는 이미 p20을 소스로 기록했다. Q의 값이 먼저 나오더라도 x5라는 이름이 같다는 이유로 그 값을 C에 전달하면 프로그램이 요구한 입력을 바꾼다. C가 기다리는 것은 “가장 최근에 나온 x5”가 아니라 목적지 p20을 만드는 특정 생산자의 결과다.

같은 저장 번호를 나중에 재사용할 수도 있으므로, 취소된 연산의 늦은 응답을 유효한 새 생산자처럼 취급해서도 안 된다. 실행 경로의 취소와 결과 유효성 규칙이 전달 경로에도 적용되어야 한다. BOOM은 추측 실행 명령에 대한 결과의 취소를 실행 장치의 계약으로 다룬다. BOOM, The Execute Pipeline

빨리 깨우는 것과 데이터가 빨리 오는 것

소비자를 실행 후보로 만드는 wakeup은 데이터 그 자체가 아니다. 일정한 지연을 갖는 생산자라면 결과가 입력 선택 시점에 도착할 것을 예상하고 소비자에게 먼저 알릴 수 있다. 그러려면 생산자가 보낸 알림과 실제 결과의 도착 시간이 맞아야 한다.

BOOM의 issue 설명에서 ALU는 issue될 때 fast wakeup을 알린다. 뒤의 데이터 전달은 bypass 경로가 담당한다. 반면 그 문서에서 bypass로 전달하지 않는 부동소수점 연산, load와 가변 지연 연산은 writeback 쪽에서 slow wakeup을 보낸다. 이 구분은 문서에 설명된 BOOM 구성의 것이다. 모든 프로세서의 load가 직접 전달될 수 없다는 보편 법칙으로 확대할 수는 없다. BOOM, Wake-up

가상의 고정 시간 ALU가 소비자 C를 깨워 놓고 예상보다 늦게 값을 낸다면, C가 준비되지 않은 입력으로 진행할 수 있다. 같은 경로에서 생산자가 취소되는 경우도 처리해야 한다. 가변 지연을 예측해 먼저 보내는 설계를 선택하려면, 실패 시 소비자를 취소하고 다시 실행하는 규칙이 추가로 필요하다. 해당 BOOM 문서는 이런 speculative issue를 향후 가능한 방식으로 구분해 설명하며, 현재 지원되는 동작으로 단정하지 않는다.

따라서 fast wakeup을 사용했다는 사실만으로 처리 속도를 보장할 수는 없다. 값이 필요한 시점과 값이 도착하는 시점, 선택 회로가 끝나는 시점까지 연결되어야 한다.

넓은 전달망은 클록을 다시 느리게 만들 수 있다

생산자 결과가 많고 소비자 입력도 많아지면 번호 비교와 데이터 선택을 여러 입력에 제공해야 한다. 먼 실행 장치 사이를 잇는 배선은 물리적인 지연과 부하를 만든다. 직접 전달로 파이프라인 사이클을 줄이려다 입력 선택 경로가 길어지면, 목표 클록에 맞추기 위해 단계를 더 나누거나 전달 대상을 제한할 수 있다.

레지스터 파일 포트가 없어도 모든 소비자를 처리할 수 있다는 결론도 나오지 않는다. 필요한 값 중 일부만 이번 사이클에 전달될 수 있고, 나머지는 여전히 정상 읽기를 해야 한다. BOOM의 설명 역시 실행 포트에 맞춰 읽기 포트를 제공하는 설계와 bypass를 함께 다룬다. 포트를 줄이고 동적으로 배분하는 선택에는 중재와 재실행 등의 복잡성이 따른다고 설명한다. BOOM, Register Read와 Dynamic Read Port Scheduling

bypass network는 데이터 의존을 없애지 않는다. C는 여전히 P가 만든 7을 필요로 한다. 그 값이 사용 가능한 순간과 저장 후 다시 읽는 순간 사이의 불필요한 기다림을 줄일 뿐이다. 생산자 번호, 응답의 유효성, 소비자의 입력 시점이 맞는 전달 경로를 만들면 의존 연산을 더 촘촘히 이어 갈 수 있다. 그 경로의 선택 비용과 배선 지연까지 맞아야 실제 실행 속도의 이점이 된다.