---
title: "같은 flit을 다시 보내도 명령은 한 번만 실행돼야 한다"
author: "브레이브브라우저쓰자"
published_at: "2026-10-30T07:41:02.949Z"
updated_at: "2026-10-06T03:19:39.119Z"
tags: ["ucie retry"]
canonical_url: "https://ariser.io/@writer_a9817d5a8de0/%EA%B0%99%EC%9D%80-flit%EC%9D%84-%EB%8B%A4%EC%8B%9C-%EB%B3%B4%EB%82%B4%EB%8F%84-%EB%AA%85%EB%A0%B9%EC%9D%80-%ED%95%9C-%EB%B2%88%EB%A7%8C-%EC%8B%A4%ED%96%89%EB%8F%BC%EC%95%BC-%ED%95%9C%EB%8B%A4"
ai_assisted: true
---

# 같은 flit을 다시 보내도 명령은 한 번만 실행돼야 한다

이 글은 AI가 활용됐습니다.

[원문](https://ariser.io/@writer_a9817d5a8de0/%EA%B0%99%EC%9D%80-flit%EC%9D%84-%EB%8B%A4%EC%8B%9C-%EB%B3%B4%EB%82%B4%EB%8F%84-%EB%AA%85%EB%A0%B9%EC%9D%80-%ED%95%9C-%EB%B2%88%EB%A7%8C-%EC%8B%A4%ED%96%89%EB%8F%BC%EC%95%BC-%ED%95%9C%EB%8B%A4)

재전송은 잃어버린 데이터를 다시 보내는 기능이지만, 이미 받은 데이터를 다시 실행하게 만들면 또 다른 오류가 된다. UCIe retry를 이해하려면 물리 링크에서 같은 flit이 두 번 나타나는 것과 상위에서 같은 동작이 두 번 수행되는 것을 분리해야 한다. 링크의 복구가 보호하는 범위를 정확히 알면 재시도 이후의 시스템 동작도 판단할 수 있다.

## 복구 기능이 켜진 모드부터 확인한다

UCIe 어댑터는 해당 모드에서 CRC와 링크 재전송을 맡는다. Raw에서는 그 경로를 우회하므로 모든 UCIe 연결에 같은 retry가 적용되는 것은 아니다. UCIe 2.0 원문은 retry의 협상 조건과 동작 규칙을 별도로 정의하며, PCIe Flit Mode의 retry를 단순화한 구조로 설명한다. [원문 92–93쪽, 3.8절](https://tmng-al.uspto.gov/resting2/api/casedoc/cms/case/99231699/tmdocument/20250612064611159321SPE0012.pdf)

CRC의 역할은 받은 바이트에 검출 가능한 오류가 있는지 확인하는 것이다. 그 바이트가 새 전송인지 이전 전송의 반복인지는 순서 상태까지 읽어야 한다. 또한 검사가 끝나기 전에 상위가 부작용을 실행하면 나중에 실패한 flit을 버려도 이미 한 일을 취소하지 못할 수 있다.

## 구멍이 생긴 순서를 자체 모델로 따라간다

설명용으로 순서 번호 10, 11, 12인 세 flit에 각각 ‘계수기를 1 증가’시키는 자체 명령 하나씩을 담자. 이 명령 형식과 다음 상태표는 표준의 모든 replay 규칙을 재현한 것이 아니라, 정상 순서를 한 번씩 전달하는 책임을 분리한 유한 모델이다. 번호는 이번 예에서 래핑하지 않고 링크 상태도 유지된다.

수신기는 CRC가 정상이고 다음에 기대한 번호인 flit만 상위에 전달한다. 10을 받아 전달하면 계수기는 1, 다음 기대 번호는 11이 된다. 11에 CRC 오류가 나면 전달하지 않는다. 그 뒤 받은 12도 아직 필요한 11이 없으므로 이 모델에서는 전달하지 않고 버린다. 계수기는 여전히 1이다.

송신기가 보관한 11과 12를 다시 보내면 수신기는 차례로 전달한다. 계수기는 2, 3이 되고 다음 기대 번호는 13이다. 단순히 재전송한 횟수만 세면 두 flit을 추가로 실행한 것처럼 보이지만, 실제 상위 전달은 총 세 번이다. 실패한 바이트의 수신과 정상 명령의 실행을 같은 사건으로 세지 않는다.

## ACK가 사라진 경우에도 이미 전달한 사실이 남는다

이번에는 수신기가 12까지 전달했는데 ACK가 송신기에 닿지 않았다고 하자. 송신기는 완료를 모를 수 있으므로 보관한 전송을 다시 내보낼 수 있다. 수신기가 정상 전달 순서의 상태를 유지한다면 이미 전달한 11이나 12를 새 명령으로 실행하지 않는다. 이 자체 모델에서 계수기는 3을 유지한다.

송신기는 ACK를 받기 전까지 필요한 flit을 보관하고, 수신기는 정상 전달과 중복 판단에 필요한 상태를 유지한다. 보관한 데이터를 일찍 지우면 다시 보낼 수 없고, 수신 순서를 매 flit마다 잊으면 잃어버린 ACK 때문에 부작용을 중복 실행할 수 있다. 복구를 데이터 복사 기능으로만 보면 두 상태의 책임을 놓친다.

실제 UCIe 2.0은 retry 관련 번호와 미확인 flit 수에 제한을 두고, reset·retrain에서의 초기화와 순서 번호 handshake도 정의한다. 이 글의 래핑 없는 정수 비교를 그대로 실제 구현에 옮기지 않는다. 유한 번호 공간에서는 이전 번호와 새 번호를 구별할 창과 규칙이 함께 필요하다.

## 링크 재전송과 명령 재발행을 구분한다

링크가 완전히 reset되어 기존 수신 상태를 잃었다면 위의 유지 조건이 달라진다. 드라이버가 완료 여부를 모르는 명령을 새 transaction으로 재발행하는 경우도 링크의 동일 flit replay와 다르다. retry가 있었다는 사실만으로 장애와 재부팅을 가로지르는 모든 동작의 exactly-once를 보장할 수 없다.

예를 들어 계수기 증가가 이미 반영됐지만 상위 완료 응답을 얻지 못한 채 장치가 재시작했다고 하자. 같은 명령을 다시 실행해도 되는지 판단하려면 상위 식별자, 완료 기록의 유지 범위, 재실행 가능한 동작인지 등의 별도 계약이 필요하다. 단순 쓰기와 증가처럼 부작용이 다른 명령에 같은 정책을 적용하면 결과가 달라질 수 있다.

그러므로 시험도 두 종류를 분리한다. CRC 오류와 ACK 손실에서는 정상 순서의 상위 전달 횟수와 송신 보관 상태를 센다. reset과 복구에서는 이전 세대의 outstanding 명령을 성공·실패·불명 중 어떻게 처리했는지 확인한다. 링크 안의 정상 복구와 시스템 재시작의 불확실성을 서로 다른 관측으로 남긴다.

UCIe retry는 검출한 전송 오류를 상위가 매번 직접 처리하지 않게 하는 장치다. 그 이득은 정상 순서, 재전송 보관, 중복 처리의 상태가 함께 유지될 때 성립한다. 같은 flit의 replay와 새 명령의 재발행을 구별하면, 링크가 해결하는 오류와 상위가 결정해야 할 복구 범위를 명확히 나눌 수 있다.

