본문 바로가기
게임 데이터 가이드

GPU 메모리 풀 관리, 텍스처 스트리밍, 캐시 프리페치 최적화

by oneplay1 2025. 10. 21.
GPU 메모리 효율은 게임의 프레임 안정성과 로딩 속도를 동시에 결정한다. 고해상도 자산이 많은 환경에서 메모리 풀 관리, 텍스처 스트리밍, 캐시 프리페치가 제대로 동작하지 않으면 버벅임(stutter)과 프레임 드랍이 발생한다. 본문은 GPU 메모리 풀 구조의 설계 원리, 텍스처 스트리밍 알고리즘, 캐시 프리페치의 적용 절차를 단계별로 해설한다. 모든 구조는 SVG 다이어그램으로 설명하며, 실제 엔진 수준의 관리 체계를 기반으로 서술한다.

GPU 메모리 풀 관리의 원리와 필요성

GPU 메모리는 CPU 메모리보다 대역폭이 넓고 접근 지연이 짧지만, 크기가 제한적이다. 고해상도 텍스처, 셰이더, 버퍼 데이터가 늘어나면 VRAM은 쉽게 포화된다. 대부분의 게임 엔진은 이를 관리하기 위해 메모리 풀(memory pool) 구조를 사용한다. 즉, 일정 크기의 메모리 블록을 미리 확보한 뒤, 필요한 리소스가 생기면 이 풀에서 분할해 사용하는 방식이다.

메모리 풀의 장점은 두 가지다. 첫째, 메모리 할당·해제를 반복하지 않아 오버헤드가 줄어든다. 둘째, GPU 드라이버의 내부 메모리 단편화를 방지할 수 있다. 하지만 블록 크기가 고정되어 있으면, 작은 텍스처를 로드할 때 낭비가 발생한다. 이를 줄이기 위해 최근 엔진들은 가변 블록 할당(variable block allocation)을 채택한다.

가변 블록 방식에서는 리소스의 실제 크기에 따라 적절한 블록을 자동 선택한다. 예를 들어 256KB 단위 풀에서 60KB 텍스처를 할당하면, 남는 공간은 인접 자산과 병합되어 캐시처럼 재활용된다. 이러한 병합·분할 작업은 GPU의 커맨드 큐와 병렬로 수행되며, 프레임 타임에 직접적인 영향을 주지 않는다.

결국 GPU 메모리 풀의 목적은 “데이터 접근 예측 가능성”이다. 즉, 필요할 때 즉시 접근 가능한 리소스를 유지하면서, 장시간의 풀락(lock)이나 비동기 로드를 방지하는 것이다.

텍스처 스트리밍의 구조와 동작 방식

텍스처 스트리밍(Texture Streaming)은 화면에 보이는 영역에 따라 필요한 텍스처만 부분적으로 로드하는 기술이다. 전체 자산을 한 번에 VRAM에 올리면 낭비가 크기 때문에, 스트리밍 엔진은 시야(View Frustum)와 거리(Distance)를 기준으로 우선순위를 부여한다.

스트리밍은 크게 세 단계로 나뉜다. ① 가시성 계산(Visibility Determination): 현재 카메라 시야에 포함된 자산을 탐색한다. ② 로드 큐 생성(Streaming Queue): 필요한 텍스처를 우선순위별로 큐에 적재한다. ③ 백그라운드 로드(Background Loading): 비동기 I/O 스레드가 데이터를 읽고 GPU로 전송한다.

이 과정에서 가장 중요한 것은 LOD(Level of Detail) 제어다. 거리에 따라 저해상도 텍스처를 우선 불러오고, 이후 고해상도로 교체하는데, 이때 교체 타이밍이 부드럽지 않으면 시각적 “팝인(pop-in)”이 생긴다. 이를 방지하기 위해 대부분의 엔진은 “이중 버퍼(double buffering)” 구조를 사용한다. 즉, 로드 중인 텍스처와 현재 사용 중인 텍스처를 분리해 GPU가 항상 안정된 데이터를 참조하게 한다.

텍스처 스트리밍 구조 가시성 계산 로드 큐 백그라운드 로드 GPU 업로드
가시성 → 큐 → 백그라운드 → GPU 업로드 순으로 처리된다.

효율적인 스트리밍을 위해서는 CPU와 GPU의 데이터 교환이 비동기화되어야 한다. 최신 API(Vulkan, DX12 등)는 비동기 복사 큐(Async Copy Queue)를 지원해, 메인 렌더 큐와 별도로 리소스를 전송할 수 있다. 이를 통해 렌더링 중에도 텍스처 로드가 가능하며, I/O 스레드에서 직접 GPU 메모리에 접근한다. 또한, “Preload Distance Threshold”라는 변수를 통해 특정 거리 이내의 오브젝트 텍스처를 미리 읽어 들인다. 이렇게 하면 플레이어가 빠르게 이동해도 로딩 지연이 발생하지 않는다.

캐시 프리페치 최적화와 예측 로드

캐시 프리페치(Cache Prefetch)는 GPU가 필요할 데이터를 미리 요청하는 기능이다. GPU는 CPU처럼 하드웨어 프리페처를 갖고 있지 않기 때문에, 엔진 수준에서 수동 예측이 필요하다. 예를 들어 플레이어가 이동 중이면, 카메라 방향과 속도를 기반으로 앞으로 1~2초 내 필요한 텍스처를 추정하여 미리 로드한다.

프리페치 전략은 두 가지가 있다. ① Spatial Prefetch: 공간 기반. 카메라 위치 주변 일정 반경 내의 리소스를 예측. ② Temporal Prefetch: 시간 기반. 최근 로드 패턴과 이동 속도에 따라 다음 프레임의 리소스를 예측. 이 두 방식을 결합하면, 로드 지연을 최대 70%까지 줄일 수 있다.

중요한 점은 프리페치가 과도하면 VRAM 점유가 급증해, 다른 리소스의 해제를 지연시킬 수 있다는 것이다. 따라서 엔진은 “프리페치 윈도우(prefetch window)”를 설정한다. 이 윈도우는 메모리 풀의 총 크기 대비 약 10~15%로 제한하며, 초과 시 가장 오래된 리소스를 순차적으로 언로드(unload)한다. 결국 프리페치 최적화의 핵심은 “예측 정확도”다. 예측이 빗나가면 오히려 메모리 낭비가 발생한다.

캐시 프리페치 루프 이동 예측 리소스 선택 로드 요청 GPU 배치
예측 → 선택 → 로드 → 배치 단계의 프리페치 순환 구조

최적화의 마지막 단계는 “메모리 재활용 정책(memory reclamation policy)”이다. 즉, 사용이 끝난 리소스를 얼마나 빨리 회수하느냐가 핵심이다. 이를 위해 LRU(Least Recently Used) 캐시 알고리즘이 적용된다. GPU 메모리에서 일정 시간 접근되지 않은 리소스는 우선순위가 낮아지며, 새로운 로드 요청이 발생하면 자동으로 덮어씌워진다. 이러한 LRU 기반 메모리 순환 정책은 대규모 오픈월드 게임의 리소스 관리에서 사실상 표준이다.

GPU 메모리 풀 계층 구조 시스템 메모리 GPU 로컬 메모리 메모리 풀 / 캐시 영역
시스템 메모리 → GPU 로컬 → 풀·캐시 계층으로 구성된다.