Follow-up to the bilingual-structure commit: docs/adr-ko/ now holds only Korean versions (24 files translated from English placeholders), ADR-0013 slug uses kebab-case in both folders, and the verify tool allows translated parenthetical commentary in the Status block. - Translate 24 English files in docs/adr-ko/ to Korean. The previous bilingual-structure commit had left these as English copies because their source content was already English; this commit fulfills the policy that docs/adr-ko/ contains only Korean. - Rename ADR-0013 in both adr/ and adr-ko/ from ver-verification_strategy.md to ver-verification-strategy.md (kebab-case consistency with other ADRs). - CLAUDE.md (ADR Translation Discipline): clarify that only the Status lifecycle keyword (Accepted / Proposed / Stub / Draft / Superseded by ADR-NNNN / Merged into ADR-NNNN) must match across EN and KO; parenthetical commentary and trailing list items may be translated. - tools/verify_adr_lang_pairs.py: replace byte-equal Status check with normalize_status_keyword() which strips parenthetical commentary and takes only the first non-empty line. - tests/test_verify_adr_lang_pairs.py: update existing test names, add coverage for translated parenthetical, translated trailing list, and Superseded-by-NNNN keyword equality. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8.9 KiB
ADR-0037: Forwarding 컴포넌트 (forwarding_v1)
Status
Accepted
Context
시뮬레이션 그래프에는 순전히 패브릭 통과를 모델링하기 위해 존재하는 노드 위치들이 많다 — NOC 메시 라우터, 스위치, UCIe 프로토콜 엔드포인트, IO 칩렛 io_noc, transit 큐브. 이들은 공통 패턴을 공유한다: 메시지를 수신하고, 컴포넌트별 오버헤드(헤더 디코드 + 라우팅 결정 시간을 모델링)를 적용하며, 사전 계산된 경로를 따라 다음 홉으로 전달한다.
본 ADR은 이러한 transit 노드에 대한 계약을 정의한다: 웜홀 cut-through
의미로 flit 인지 포워딩을 처리하는 단일 컴포넌트 타입(TransitComponent)이며,
각 인스턴스가 수행하는 개념적 역할에 따라 여러 impl 이름 아래에 사용된다.
Decision
D1. 역할
Forwarding 컴포넌트(TransitComponent 클래스)는 시뮬레이션 그래프의
상태 없는 transit 노드이다. 메시지가 물리적으로 통과하지만 의미론적
처리는 일어나지 않는 모든 패브릭 위치를 모델링한다.
통과당 컴포넌트는:
in_port에서 들어오는 Transaction 또는 Flit을 읽는다.- 설정된 컴포넌트별 오버헤드(
overhead_ns)를 적용한다. 멀티 flit 페이로드라도 Transaction당 한 번 적용된다(D2 참조). - Transaction의 사전 계산된
path를 따라 다음 홉을 조회한다. - 해당
out_port로 전달한다; 종단 노드(다음 홉 없음)에서는is_lastflit이 도착하면txn.done을 시그널한다.
본 컴포넌트는 다음을 하지 않는다:
- 라우팅 결정 — 경로는 라우터에 의해 사전 계산된다(ADR-0002 / ADR-0017 D2). Forwarding은 홉별 단계만 실행한다.
- 와이어 전파나 대역폭 점유 모델링 — 컴포넌트 사이의 별도 와이어 프로세스가 처리한다(ADR-0015 D2).
- 주소 해석 — AddressResolver가 담당한다(ADR-0017 D9).
- 완료 집계 — 종단 엔드포인트(IO_CPU, M_CPU, HBM_CTRL)가 담당한다.
D2. First-flit 오버헤드 모델 (헤더 디코드)
Transaction별 overhead_ns는 첫 flit 도착 시 정확히 한 번 적용된다:
_txn_decoded: set[int]이 본 노드에서 이미 오버헤드를 지불한 Transaction들을 추적한다.- 어떤 Transaction의 첫 flit 도착 시:
yield self.run(env, msg.txn.nbytes)— 오버헤드를 지불한다. - 동일 Transaction의 후속 flit들은 오버헤드를 건너뛰고 추가 지연 없이 파이프라인 통과한다.
is_lastflit 시: Transaction을_txn_decoded에서 제거한다.
이는 실제 HW의 동작 — 헤더 디코드와 라우팅 결정이 첫 flit에서 한 번 일어나고, 이후 페이로드 flit들은 같은 경로로 스트리밍되는(웜홀 cut-through) — 을 모델링한다. 멀티 홉 파이프라이닝은 자연스럽게 발현된다 — 각 홉이 자신의 first-flit 오버헤드를 추가하지만, 첫 flit 이후의 flit들은 이미 첫 flit이 통과한 어떤 홉에서도 오버헤드를 다시 지불하지 않는다.
D3. 직렬 워커 포워딩 (순서 보존)
본 컴포넌트의 워커는 _inbox에서 flit을 소비하여 도착 순서대로 직렬
포워딩하는 단일 SimPy 프로세스이다. 컴포넌트는 flit마다
env.process(...)를 spawn하지 않는다.
근거: 첫 flit이 overhead_ns에서 yield하는 동안 후속 flit이 병렬
프로세스에서 실행되면, 후속 flit이 첫 flit을 추월할 수 있다. 이는 순서가
어긋난 전달을 낳고, is_last flit이 첫 flit보다 먼저 목적지에 도착하게
하여 — 트랜잭션의 완료 의미와 다운스트림의 flit 인덱스 기반 처리 모두를
손상시킨다.
D4. 경로 기반 next-hop 라우팅
라우팅은 Forwarding 컴포넌트의 관심사가 아니다. Transaction은 라우터에
의해 사전 계산된 path(ADR-0002 / ADR-0017 D2)와 함께 도착한다.
컴포넌트는 단지 자신의 경로상 위치를 찾아 path[index + 1]로 전달한다:
def _next_hop_in_path(self, txn):
my_id = self.node.id
path = txn.path
for i, n in enumerate(path):
if n == my_id and i + 1 < len(path):
return path[i + 1]
return None
next_hop이 발견되고 out_ports에 존재하면 flit이 전달된다. 그렇지
않으면(종단 노드) is_last flit이 도착할 때 txn.done.succeed()가
호출된다.
D5. Flit 인지 모드와 Non-Flit 폴백
_FLIT_AWARE = True는 본 컴포넌트가 베이스 클래스의 _fan_in 내 flit
재조립 로직에서 제외되도록 한다. Flit은 재조립 없이 _inbox에 직접
놓이며, 이는 워커 루프(D2, D3)에서의 per-flit 처리를 가능케 한다.
Non-Flit 메시지 — 0바이트 제어 Transaction이나 그 외 청크화되지 않는
페이로드 — 는 env.process를 통해 베이스 클래스의 레거시 _forward_txn
경로로 빠진다. 이는 flit 수준 처리의 이득이 없는 제어 평면 트래픽에
대한 하위 호환성을 보존한다.
D6. 베이스 클래스에서의 멀티 스트림 병합
라우터에서의 멀티 스트림 FIFO 병합은 Forwarding이 아닌 베이스 클래스의
책임이다. 베이스 클래스의 _fan_in은 in_port마다 하나의 프로세스를
spawn한다; 모두가 공유된 단일 _inbox에 push한다. 따라서 서로 다른
업스트림 스트림의 flit들은 _inbox의 FIFO 순서로 flit 단위에서
인터리브된다.
Forwarding 워커는 단지 _inbox를 도착 순서대로 소비할 뿐이다 —
공유 inbox 위의 공정 FIFO로 라우터별 멀티 플로우 중재를 올바르게
모델링한다.
D7. 여러 impl 이름 아래의 단일 구현
단일 TransitComponent 클래스가 components.yaml에서 네 가지 impl
이름으로 등록된다:
builtin.forwarding— 범용 forwarding (예:io_noc,noc_router, UCIe conn 브리지)builtin.switch— 트레이 수준 스위치builtin.noc— 큐브 수준 NOC 패브릭(레거시 싱글톤; 현재 NOC 라우터는builtin.forwarding을 사용)builtin.ucie— UCIe 프로토콜 엔드포인트
네 별칭 모두 동일한 동작을 갖는 동일한 클래스를 인스턴스화한다.
인스턴스별 차별화는 attrs.overhead_ns에만 존재한다. 별도 impl 이름이
존재하는 것은 가독성을 위한 의도 태그이자, 하위 호환을 깨지 않고 향후
분기를 허용하기 위함이다.
D8. 설정 가능한 overhead_ns
단일 속성이 인스턴스별 레이턴시를 결정한다:
| 사용 사이트 | impl 이름 | overhead_ns |
|---|---|---|
| 트레이 수준 스위치 | builtin.switch |
5.0 |
| 큐브 NOC 라우터 | builtin.forwarding |
2.0 |
| IO 칩렛 io_noc | builtin.forwarding |
0.0 |
UCIe 프로토콜 엔드포인트(ucie-{N,S,E,W}) |
builtin.ucie |
8.0 |
UCIe conn 브리지(ucie-{PORT}.conn{N}) |
builtin.forwarding |
0.0 |
기본값은 0.0이다. 속성은 매 run() 호출에서 읽히므로 동적 재설정이
가능하나 현재는 사용되지 않는다.
Consequences
Positive
- 단일 클래스가 시뮬레이션 그래프의 모든 transit 노드 역할을 처리한다 — 개체 수가 많은 컴포넌트 타입에 대한 최소 코드 표면.
- Flit 인지 처리 + 직렬 워커는 per-flit 프로세스 오버헤드 없이 멀티 홉 경로 전반에 걸쳐 웜홀 의미를 보존한다.
overhead_ns만이 유일한 인스턴스별 튜너블이다; 라우팅, 대역폭, 주소 해석은 자체 컴포넌트/모듈에서 깨끗이 분리되어 있다.- 멀티 스트림 병합이 베이스 클래스 구조에서 자연스럽게 발현된다; 라우터 전용 로직이 공정 FIFO 중재를 중복 구현하지 않는다.
- Non-Flit 폴백 경로는 모든 메시지를 flit 프레임워크로 강제하지 않고도 제어 평면 트래픽이 계속 동작하도록 한다.
Negative
- 단일 클래스가 사용 사이트의 의도를
attrs.overhead_ns설정 안에 숨긴다; 어떤 impl 이름이 어떤 동작 클래스로 매핑되는지 보려면 독자가topology.yaml+components.yaml을 참조해야 한다. - per-flit 직렬 워커는
overhead_ns가 크고 같은 라우터에 다수의 동시 트랜잭션이 도착할 때 병목이 된다; 현재 값(0–8 ns)에서는 무시할 만한 수준이다.
Links
- ADR-0002 (라우팅 거리 — 경로 계산)
- ADR-0015 D1 (컴포넌트 포트 모델)
- ADR-0015 D2 (와이어 프로세스 — 본 컴포넌트와 별개의 BW + 전파)
- ADR-0015 D6 (Transit 큐브 forwarding 패턴)
- ADR-0016 D1 (IO 칩렛 io_noc — 본 컴포넌트 사용)
- ADR-0017 D1 (큐브 NOC 라우터 — 본 컴포넌트 사용)
- ADR-0017 D6 (UCIe 분해 —
ucie-{PORT}인스턴스가 본 컴포넌트 사용) - ADR-0033 D1 (Flit 인지 통과, first-flit 오버헤드, 멀티 스트림 병합 의미)