모든 이야기

한 줄짜리 식이 네 사이클 또는 일곱 사이클이 되는 이유

a*b+c*d는 한 줄이다. 하드웨어에서도 한 번의 클록으로 끝날 것 같지만, 같은 식이 어떤 구성에서는 네 사이클, 다른 구성에서는 일곱 사이클이 걸릴 수 있다. 소스의 줄 수에는 연산기의 지연과 개수가 들어 있지 않기 때문이다. HLS scheduling은 이 빈칸을 채워, 각 연산을 언제 시작할지 정한다.

문장의 순서에서 필요한 값의 순서로

설명용 계산을 세 연산으로 나누자. p=a×b, q=c×d, y=p+q다. 입력 네 개는 시각 0부터 사용할 수 있다. p와 q는 서로의 결과를 읽지 않으므로 동시에 시작할 여지가 있다. 반면 y는 두 곱셈 결과가 모두 나온 뒤에 시작해야 한다.

연산 u의 시작 시각을 S(u), 결과가 나오기까지의 시간을 L(u)라고 하면, u의 결과를 사용하는 v에는 다음 조건이 필요하다.

S(v) ≥ S(u)+L(u)

여기서 시각은 정수 사이클 경계다. 시작 0, 지연 3인 곱셈의 결과는 경계 3에서 사용할 수 있다. 지연 1인 덧셈을 그때 시작하면 결과는 경계 4에 나온다. 사이클 번호를 세는 방식이 다르면 보고서 숫자가 달라 보일 수 있으므로, 이 예제는 시작과 완료를 모두 경계 시각으로 쓴다.

CIRCT의 정적 scheduling 설명은 입력 연산과 의존 관계에 연산기 지연을 붙이고, 시작 시각이 그 제약을 지키는지 검증하는 구조를 보여준다. 소스의 값 전달로 드러나지 않는 메모리나 제어 의존성은 추가 관계로 표현할 수 있다. 독립적인 식처럼 보인다는 판단도 실제 접근 주소와 부작용까지 확인해야 한다.

곱셈기의 개수를 바꾸어 같은 식을 배정한다

이제 곱셈 지연은 3사이클, 덧셈 지연은 1사이클이라고 가정하자. 메모리 접근과 인터페이스 지연은 없고, 덧셈기는 한 개다. 실제 장치의 합성 결과가 아닌 자체 시간표다.

구성p 시작→완료q 시작→완료덧셈 시작→완료
곱셈기 두 개0→30→33→4
매 사이클 입력을 받는 곱셈기 한 개0→31→44→5
완료 후에만 다음 입력을 받는 곱셈기 한 개0→33→66→7

둘째 구성에서는 p가 끝나기 전에 q를 시작한다. 한 개의 파이프라인 곱셈기 내부에 서로 다른 계산이 다른 단계에서 진행되는 것이다. ‘곱셈기가 한 개’라는 설명만으로 셋째 구성의 시간표를 적용하면, 연산 완료 시간과 다음 입력 수락 간격을 혼동하게 된다.

입력 a=2, b=3, c=4, d=5를 넣으면 세 구성 모두 y=26을 계산한다. 이 예제에서는 값이 같아도 완료 시각은 4, 5, 7로 다르다. 공유를 늘리는 선택은 연산기 수를 줄이면서 다른 시간표를 만든다. 어느 구성이 더 좋은지는 완료 기한, 연속 입력량, 구현 자원을 함께 놓고 판단해야 한다.

빠른 클록이 연산을 더 작은 시간 칸에 넣는다

사이클 단위의 지연 역시 처음부터 고정된 자연 상수는 아니다. 조합 논리의 전파 시간이 목표 클록의 한 칸에 들어가는지에 따라 레지스터 경계가 달라질 수 있다.

별도의 단순 예제로 덧셈 두 개가 각각 2ns 걸리고, 그 외 경로에 1ns의 여유가 필요하다고 하자. 5ns 주기에서는 계산에 쓸 수 있는 4ns에 두 덧셈을 이어 넣을 수 있다. 주기를 3ns로 줄이면 계산 예산은 2ns여서 같은 연결을 한 사이클에 넣을 수 없다. 연산을 나누면 시간표의 사이클 수가 늘 수 있다.

이는 실제 셀이나 배선의 지연 예측이 아니다. 두 연산의 지연이 단순히 더해진다는 가정 아래, 클록 목표와 시간표가 연결된다는 점을 보여준다. 실제 구현은 입력 전이, 부하, 배선, 제어 경로와 레지스터 지연까지 확인해야 한다. 사이클 수가 짧다는 이유만으로 물리적으로 빠른 회로라고 결론 낼 수 없는 이유다.

HLS scheduling 결과를 읽을 때는 가장 긴 의존 경로와 같은 시간에 요구되는 자원을 먼저 찾을 수 있다. 독립 연산을 동시에 시작하지 못했다면 값이 없었는지, 연산기가 부족했는지, 메모리 포트가 막혔는지를 구분한다. 서로 다른 원인을 같은 ‘컴파일러가 느리게 만들었다’는 말로 묶으면 바꿀 지점을 놓친다.

시간표의 검증도 그 모델 안에서 이루어진다. 앞의 둘째 구성에서 q를 0으로 당기면 한 자원의 입력 칸에 두 계산이 겹친다. 반대로 q는 1에 둔 채 덧셈만 3으로 당기면 q가 아직 준비되지 않는다. 두 실패는 자원 충돌과 값 의존 위반으로 다르다. 빠르게 보이는 시간표라도 각각의 제약을 통과해야 사용할 수 있다. 메모리 주소의 별칭 관계를 모델에서 빠뜨렸다면, 그 시간표를 검사해 성공했다는 결과 역시 실제 프로그램의 순서까지 검증하지 못한다.

한 줄짜리 식이 여러 사이클이 되는 이유는 문장을 길게 풀어 썼기 때문이 아니다. 필요한 값이 도착하는 시각과 자원을 다시 사용할 수 있는 시각을 지켜야 하기 때문이다. 그 두 조건을 시간표에 적으면, 지연을 줄이기 위해 연산기를 늘릴지, 파이프라인을 바꿀지, 입력 구조를 손볼지가 구체적인 선택이 된다.

한 줄짜리 식이 네 사이클 또는 일곱 사이클이 되는 이유 · ariser