GPU 명령 버퍼 스트리밍의 개념과 설계 원리
GPU 명령 버퍼(Command Buffer)는 렌더링 작업을 수행하기 위한 GPU 명령의 집합이다.
CPU가 생성하고, GPU가 실행한다.
과거에는 한 프레임 단위로 명령 버퍼를 만들고 폐기하는 구조였지만,
현대 엔진에서는 “스트리밍(Streamed Command Buffer)” 구조를 사용한다.
스트리밍 구조는 버퍼를 지속적으로 재활용하며,
렌더링 중에도 실시간으로 새로운 커맨드를 추가할 수 있도록 설계된다.
이 방식의 핵심은 **고정 버퍼 풀(Fixed Buffer Pool)** 과 **순환 스트림(Ring Stream)** 구조다.
CPU는 버퍼 풀에서 빈 슬롯을 가져와 명령을 작성하고,
GPU는 사용이 끝난 슬롯을 즉시 반환한다.
이 구조는 CPU와 GPU의 실행 파이프라인을 완전히 분리시켜
병목 없이 동시 실행을 가능하게 한다.
스트리밍 방식의 명령 관리만으로도 GPU 사용률이 평균 10~15% 향상된다.
또한 렌더링 중 동적 객체가 많을 때도, 버퍼 관리가 예측 가능해 프레임 타임 안정성이 높아진다.
스트리밍 버퍼의 설계에서 중요한 점은 메모리 일관성이다. CPU가 작성 중인 버퍼를 GPU가 동시에 접근하면 충돌이 발생한다. 이를 방지하기 위해 “Fence Sync” 또는 “Write Pointer Validation” 방식이 사용된다. 각 버퍼 슬롯은 상태 플래그를 가지며, CPU는 GPU가 해당 슬롯을 해제한 것을 확인한 뒤 다시 재사용한다. 이 구조 덕분에 버퍼 풀의 크기를 작게 유지해도 안정적인 스트리밍이 가능하다.
비동기 큐 처리와 GPU 파이프라인 분리
GPU는 그래픽 작업만 수행하지 않는다.
렌더링, 컴퓨트, 데이터 전송이 동시에 이루어진다.
이 세 가지를 효율적으로 병렬화하기 위해
**비동기 큐(Asynchronous Queue)** 구조가 사용된다.
DirectX 12와 Vulkan은 그래픽, 컴퓨트, 전송 큐를 각각 별도로 제공하며,
엔진은 이를 동적으로 스케줄링한다.
비동기 큐의 장점은 GPU가 한 작업을 기다리지 않고 다른 큐의 작업을 수행할 수 있다는 것이다.
예를 들어, 그래픽 큐가 그림자 렌더링을 수행하는 동안,
컴퓨트 큐는 조명 계산을 병렬로 처리할 수 있다.
이렇게 되면 GPU 점유율이 균형을 이루고, 전체 프레임 처리 효율이 향상된다.
하지만 큐 간 리소스 접근이 충돌하면 GPU 오류가 발생할 수 있다.
이를 방지하기 위해 “Queue Ownership Transfer” 절차가 필요하다.
이 과정은 GPU 내부에서 리소스의 소유권을 변경하여,
한 큐가 작업을 끝내야 다른 큐가 접근할 수 있도록 보장한다.
엔진은 이를 자동화해, 개발자가 수동으로 동기화를 제어하지 않아도 된다.
비동기 큐 구조의 성능 향상 효과는 특히 고해상도 렌더링에서 두드러진다. GPU는 대량의 텍스처 업로드와 쉐이더 계산을 동시에 수행할 수 있으므로, CPU-GPU 간 대기 시간이 줄어든다. 또한 일부 엔진은 큐를 우선순위로 분류한다. 실시간 인터랙션이 필요한 큐(예: UI, 조작 입력)는 높은 우선순위를 부여받고, 백그라운드 큐(예: 리소스 로드)는 낮은 우선순위로 실행된다. 이런 큐 스케줄링만으로도 프레임 타임의 변동 폭이 최대 40% 감소한다.
렌더 파이프라인 프리패칭과 사전 로딩 구조
렌더 파이프라인 프리패칭(Render Pipeline Prefetching)은
렌더링 중 필요할 자원을 CPU가 미리 준비해 GPU에 전달하는 구조다.
즉, GPU가 명령을 실행하기 전에 CPU가 다음 프레임의 파이프라인을 예측하고 생성한다.
이 기법은 특히 대형 오픈월드나 복잡한 장면에서 유용하다.
프리패칭 시스템은 렌더링 예측 모델을 기반으로 동작한다.
카메라 이동, 플레이어 위치, 가시 범위를 분석해
다음 프레임에서 필요한 쉐이더·메시·텍스처를 사전에 큐에 로드한다.
이를 통해 GPU가 자원을 요청할 때 즉시 사용 가능 상태가 된다.
엔진 내부에서는 “Prefetch Manager”가 이를 제어한다.
매 프레임마다 GPU의 현재 파이프라인 상태를 점검하고,
다음 프레임에서 예상되는 파이프라인 구성을 캐시에 미리 구축한다.
이렇게 하면 프레임 경계(Frame Boundary)에서 발생하는 셰이더 재컴파일과 캐시 미스를 줄일 수 있다.
프리패칭은 CPU의 유휴 시간을 활용하는 대표적 최적화다.
GPU가 렌더링 중일 때 CPU는 다음 프레임을 위한 데이터를 준비한다.
이 구조는 병렬 처리 효율을 극대화하며,
복잡한 장면에서도 일정한 렌더 타임을 유지하게 만든다.
결과적으로 프레임 드롭이 줄어들고,
GPU 사용률이 안정적으로 95% 이상 유지된다.
이 모든 시스템은 단순한 속도 향상만이 아니라
GPU 리소스의 “예측 가능한 일관성”을 보장한다는 점에서 중요하다.
렌더링 과정에서 미세한 지연도 제거함으로써
플레이어는 자연스러운 프레임 전환과 시각적 안정성을 경험하게 된다.