---
title: "버퍼에 공간이 남아도 다음 데이터를 못 보내는 이유"
author: "브레이브브라우저쓰자"
published_at: "2026-10-28T13:36:03.864Z"
updated_at: "2026-10-06T02:57:21.629Z"
tags: ["credit flow control"]
canonical_url: "https://ariser.io/@writer_a9817d5a8de0/%EB%B2%84%ED%8D%BC%EC%97%90-%EA%B3%B5%EA%B0%84%EC%9D%B4-%EB%82%A8%EC%95%84%EB%8F%84-%EB%8B%A4%EC%9D%8C-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A5%BC-%EB%AA%BB-%EB%B3%B4%EB%82%B4%EB%8A%94-%EC%9D%B4%EC%9C%A0"
ai_assisted: true
---

# 버퍼에 공간이 남아도 다음 데이터를 못 보내는 이유

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

[원문](https://ariser.io/@writer_a9817d5a8de0/%EB%B2%84%ED%8D%BC%EC%97%90-%EA%B3%B5%EA%B0%84%EC%9D%B4-%EB%82%A8%EC%95%84%EB%8F%84-%EB%8B%A4%EC%9D%8C-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A5%BC-%EB%AA%BB-%EB%B3%B4%EB%82%B4%EB%8A%94-%EC%9D%B4%EC%9C%A0)

수신 버퍼가 네 칸인데 네 flit을 보낸 다음 링크가 잠시 쉰다. 수신기는 빠르게 비우고 있고 전선도 비어 있다. 그래도 송신기는 빈 공간이 돌아왔다는 확인을 아직 받지 못했다. credit flow control에서는 실제로 생긴 공간과 송신기가 사용할 수 있다고 알고 있는 공간 사이의 시간이 처리율을 결정한다.

## credit은 남은 공간의 예약권이다

수신 측의 빈 슬롯 하나에 대응하는 credit을 송신 측이 가진다고 하자. 송신기는 flit을 보낼 때 credit 하나를 사용한다. flit이 아직 전선을 이동 중이어도 그 슬롯을 다른 전송에 다시 배정하지 않는다. 수신 측에서 flit을 처리해 슬롯을 비우면 credit을 되돌려 주고, 송신기는 반환을 확인한 뒤 다시 사용할 수 있다.

중간의 왕복 시간을 무시하고 수신기 현재 점유량만 송신기의 숫자로 삼으면, 아직 도착하지 않은 flit을 위한 공간을 중복 예약할 수 있다. Dally의 구현 설명도 전송 측에서 수신 대기열의 여유를 관리하고, 반대 방향으로 버퍼 가용 정보를 전달하는 구조를 설명한다. [원문 PDF 4–5쪽, III절](https://groups.csail.mit.edu/cag/PSRG/papers/dally-ieee92.pdf)

슬롯 총수를 B라 하고, 사용 가능한 credit C, 이동 중인 flit F, 수신 버퍼에 있는 flit O, 아직 송신기에 도착하지 않은 반환 credit K를 세자. 슬롯당 credit을 하나씩 정확히 관리하는 이 모델에서 `C+F+O+K=B`다. 어떤 슬롯이 한 단계에서 다음 단계로 옮겨 갈 뿐, 동시에 두 전송의 공간이 되지 않는다.

## 네 credit으로 왕복 여섯 cycle을 버틴다

자체 시간 모델을 정하자. 링크는 한 cycle에 한 flit을 보낼 수 있고 B = 4다. cycle t에 보낸 flit은 t+2의 시작에 수신 버퍼에 도착하고 t+3의 시작에 소비된다. 그 반환 credit은 t+6의 시작에 송신기가 확인한다. 따라서 하나의 credit을 재사용하기까지 R = 6cycle이다.

cycle 시작에 도착한 credit을 그 cycle의 전송에 바로 쓸 수 있다고 정하면 송신은 cycle 0, 1, 2, 3에 가능하다. cycle 4와 5에는 credit이 없어서 쉰다. cycle 6에 첫 credit이 돌아오고, 6, 7, 8, 9에 다시 네 flit을 보낸다. 이 패턴이 지속되면 여섯 cycle에 네 flit, 즉 평균 2/3 flit/cycle이다.

cycle 4 시작을 자세히 보자. 보낸 네 flit 중 두 개는 이미 소비되어 credit이 돌아오는 중이다. 하나는 수신 버퍼에 있고 하나는 이동 중이다. 따라서 C = 0, F = 1, O = 1, K = 2이며 합은 여전히 4다. 수신 버퍼가 실제로 네 칸 모두 차 있지 않아도 송신기는 보낼 수 없다. 나머지 공간의 예약권이 아직 반환되지 않았기 때문이다.

## 깊이는 왕복 시간과 비교한다

같은 모델에서 B = 6이면 cycle 0–5에 여섯 flit을 보내고, cycle 6부터 첫 credit을 재사용한다. 수신기와 중재가 계속 준비되어 있다면 끊기지 않고 한 flit/cycle을 유지한다. 이 이상화된 한 링크에서 전속 전송의 조건은 `B≥R`이다. B가 작으면 지속 처리율의 상한은 `min(1,B/R)` flit/cycle로 나타난다.

여기서 R은 반환 회로의 지연만이 아니다. flit이 이동하고 버퍼에서 소비될 때까지의 시간, credit이 돌아오는 전선과 처리 단계가 모두 포함된다. BookSim의 credit_delay 항목도 credit 처리 지연에 전선 지연을 포함하지 않는다고 명시한다. [공식 Router organizations 설정](https://github.com/booksim/booksim2/blob/master/doc/manual.tex)

도착한 credit을 다음 cycle부터만 사용한다면 위 식의 R을 그 규칙에 맞게 다시 세야 한다. 경계에서 한 cycle을 빠뜨리면 버퍼가 충분하다는 계산과 실제 링크의 빈 cycle이 어긋난다. 숫자를 쓰기 전에 반환이 어느 cycle의 중재에 보이는지 정해야 한다.

## 소비가 멈추면 credit도 돌아오지 않는다

`B≥R`은 수신기가 정해진 시간에 소비한다는 예제의 조건이다. 후속 라우터가 막히면 O에 flit이 더 오래 남고 반환 시간도 늘어난다. 네트워크 전체의 혼잡을 고정된 R 하나로 제거할 수는 없다. 더 깊은 버퍼는 잠깐의 정체를 흡수하지만 출력의 지속 용량보다 많은 입력을 영원히 받아 주지 못한다.

반환 credit의 누락은 사용할 수 있는 공간을 잃게 하고, 중복 credit은 공간을 실제보다 크게 세어 넘침을 만들 수 있다. 리셋으로 양쪽 점유 상태가 달라지는 경우도 같은 문제를 낳는다. 카운터가 음수가 아닌지만 검사하지 말고, 전송·소비·반환의 보존 관계를 확인해야 한다. BookSim의 BufferState도 전송과 반환 때 점유량을 반대 방향으로 갱신하고 범위를 검사한다. [실제 구현의 SendingFlit과 ProcessCredit](https://github.com/booksim/booksim2/blob/master/src/buffer_state.cpp)

credit flow control의 설계 질문은 ‘버퍼가 몇 칸인가’에서 끝나지 않는다. 한 칸의 예약권이 언제 돌아오는지, 그 시간 동안 몇 flit을 보내야 하는지까지 계산한다. 전선은 비어 있고 수신기에도 공간이 있는데 송신이 멈춘다면, 이 왕복 시간과 송신기에서 보이는 credit의 흐름이 먼저 확인할 대상이다.

