[CS] 게임 개발자를 위한 컴퓨터 구조와 데이터의 이해
2026. 3. 9. 14:13ㆍComputer Science
언리얼 엔진 5와 C++ 환경에서 개발하다 보면, 어느 순간 프레임 드랍이나 원인을 알 수 없는 병목 현상과 마주하게 됩니다. 화려한 이펙트와 복잡한 물리 연산을 완벽하게 제어하고 최적화의 한계를 돌파하기 위해서는, 우리가 작성한 코드와 에셋이 하드웨어 레벨에서 어떻게 처리되는지 그 깊은 속사정을 파헤쳐 보아야 합니다.
1. 언리얼 개발자가 '컴퓨터 구조'를 알아야 하는 이유
언리얼 엔진은 현존하는 가장 강력한 툴이지만 그만큼 하드웨어 자원을 극한으로 사용합니다. 블루프린트 노드를 잘 배치하고 C++ 문법을 아는 것만으로는 최적화된 고퀄리티 게임을 만들 수 없으며, 하드웨어의 데이터 처리 방식을 알아야 진정한 성능을 끌어낼 수 있습니다.
- 근본적인 문제 해결 역량: 프레임이 떨어지거나(Stuttering) 크래시가 발생할 때, 컴퓨터 구조를 아는 개발자는 병목 현상(Bottleneck)이 CPU 연산, GPU 대역폭, 혹은 VRAM 부족 중 어디에서 기인하는지 파악할 수 있습니다. 가비지 컬렉션(GC)이나 드로우 콜(Draw Call)의 하드웨어적 작동 원리를 이해하면 스스로 해결책을 찾을 수 있습니다.
- 최적화의 기술: 고해상도 텍스처를 무작정 넣는 대신 하드웨어의 캐시 메모리와 VRAM 용량을 고려해 텍스처 스트리밍 수치를 조절해야 합니다. 데디케이티드 서버(Dedicated Server) 개발 시 CPU 멀티코어 프로세싱 원리를 활용하면 훨씬 적은 비용으로 더 많은 동시 접속자를 수용할 수 있습니다. 나나이트(Nanite)나 루멘(Lumen) 역시 하드웨어 아키텍처를 극한으로 활용한 기술입니다.
- 커리어의 차별점: "Ticking 시스템이 CPU 스케줄링에 미치는 영향"이나 "C++ 메모리 레이아웃과 캐시 적중률(Cache Hit)의 상관관계"는 게임 회사 기술 면접의 단골 질문입니다. 이를 아는 사람은 단순한 툴 사용자가 아닌 '엔지니어'로 대우받습니다.
2. 컴퓨터의 4가지 핵심 부품과 시스템 아키텍처
복잡한 데스크톱부터 모바일 기기까지, 언리얼 엔진을 구동하는 핵심 부품은 크게 4가지로 나뉩니다. 이 장치들은 메인보드(Motherboard)라는 큰 회로판에 장착되어 시스템 버스(System Bus)라는 데이터 이동 통로를 통해 서로 데이터와 신호를 주고받습니다.
- CPU (중앙처리장치): 컴퓨터의 두뇌로, 산술논리연산장치(ALU), 제어장치, 레지스터로 구성되어 게임 로직, 물리 연산, AI 등의 명령을 해석하고 실행합니다.
- 메모리 (주기억장치, RAM): 현재 실행 중인 프로그램과 레벨, 에셋이 임시로 올라가 있는 고속 작업대입니다. 컴퓨터가 작동하는 원리를 이해하려면 데이터를 자유롭게 읽고 쓸 수 있는 공간인 RAM의 역할을 아는 것이 가장 중요합니다.
- 보조기억장치: SSD나 HDD처럼 전원이 꺼져도 데이터를 영구적으로 보관하는 거대한 창고로, 콘텐츠 브라우저의 모든 파일이 저장됩니다.
- 입출력장치 (I/O Device): 사용자와의 상호작용을 담당하며, 키보드/마우스의 입력과 모니터로 렌더링 된 화면 출력을 처리합니다.
3. 컴퓨터가 이해하는 세계: 데이터와 명령어
엔진이 하드웨어와 소통하는 언어는 결국 0과 1의 거대한 흐름이며, 이는 크게 데이터(Data)와 명령어(Instruction)로 나뉩니다.
- 데이터 (에셋과 리소스): 텍스처(.png), 스태틱 메시(.fbx), 사운드 웨이브(.wav) 등 콘텐츠 브라우저에 있는 에셋들입니다. 그 자체로는 아무것도 하지 않는 정적인 0과 1의 덩어리입니다.
- 명령어 (블루프린트와 C++ 코드): 데이터를 움직이고 계산하여 화면에 뿌리게 만드는 실질적인 행동 대장입니다. "메시에 텍스처를 입혀서 월드 좌표 (0,0,0)에 배치해라"와 같이 컴퓨터에게 내리는 지시입니다.
- 게임 클라이언트는 결국 거대한 명령어들의 집합이라고 정의할 수 있습니다.
4. 데이터의 최소 단위와 인코딩 전략
언리얼 엔진에서 구현하는 화려한 이펙트도 하드웨어 레벨에서는 0과 1의 조합일 뿐입니다.
정보의 최소 단위와 크기
- 비트(Bit): 컴퓨터가 이해하는 가장 작은 정보 단위로 전구의 꺼짐/켜짐과 같습니다. $n$개의 비트로 표현할 수 있는 상태는 $2^n$가지입니다.
- Unreal Dev Tip: 언리얼에서 bool 변수는 논리적으로 1비트지만, 실제 메모리 레이아웃에서는 하드웨어 처리 효율을 위해 바이트 단위로 저장되는 경우가 많으며 이는 대규모 최적화에 영향을 줍니다.
- 바이트(Byte) 및 그 이상: 8비트를 하나로 묶어 1바이트(Byte)라 부르며 256가지 정보를 표현합니다. 이후 1,000배수 기준으로 KB(설정 파일 수준), MB(텍스처 에셋 수준), GB(프로젝트 패키지 수준), TB(대규모 서버 보관소)로 단위가 확장됩니다.
텍스트 인코딩 과정
- 문자 집합 (Character Set): 컴퓨터가 인식할 수 있는 문자의 도감입니다. 128개를 정의한 기본적인 ASCII(아스키)와 현대 언리얼 개발의 표준이자 전 세계 모든 언어를 포함하는 거대한 유니코드(Unicode)가 있습니다.
- 인코딩과 디코딩 (Encoding & Decoding): 사람이 읽는 문자를 0과 1로 번역하는 것이 인코딩, 그 반대가 디코딩입니다. 이 둘의 규칙이 다르면 '글자 깨짐' 현상이 발생합니다
- 외부 데이터(CSV, JSON 등)을 언리얼로 가져올 때 글자가 깨진다면, 파일의 저장 인코딩(주로 UTF-8 with BOM)과 엔진의 디코딩 설정이 맞지 않기 때문입니다.
- UTF-8: 전 세계 표준 방식.
- UTF-16: 언리얼 엔진이 FString을 처리할 때 사용하는 주요 방식.
- 언리얼 문자열 타입 비교:
- FString: 편집이 자유롭고 내부적으로 인코딩/디코딩이 활발하게 일어납니다.
- FText: 로컬라이징(다국어 지원)의 핵심으로 엔진 차원에서 디코딩을 보장합니다.
- FName: 문자열을 고유한 ID(숫자)로 인코딩하여 이름표로서의 성능 최적화에 특화되어 있습니다.
에셋의 인코딩
- 텍스처: 픽셀의 색상을 비트 심도(Bit Depth)에 따라 인코딩합니다. 8비트는 256단계, 16비트는 65,536단계로 밝기를 표현합니다. 원본은 용량이 커서 GPU가 빠르게 읽을 수 있도록 BC7, ASTC 같은 특수 압축 방식으로 인코딩해 VRAM에 저장합니다.
- 메시: 공간상의 정점(Vertex) 위치 정보는 실수형(Float) 데이터로 인코딩됩니다.
- 디코딩 연산: 하드웨어가 화면을 그릴 때 ALU가 부동 소수점 좌표값을 읽어 들이고, 명령어에 따라 계산하여 월드 좌표에 배치합니다.
5. 소스코드와 명령어: 코드에서 기계어까지
고급 언어와 저급 언어
- 고급 언어: C, C++, Python 등 사람이 이해하기 쉽게 만들어진 언어입니다.
- 저급 언어: 0과 1로 된 기계어와, 이를 사람이 읽기 편하게(push, mov 등) 1:1로 번역한 어셈블리어가 있습니다.
- Unreal Dev Tip: 코드 수준에서 프레임 저하 원인을 찾을 수 없을 때 컴파일된 어셈블리 코드를 뜯어보면, 불필요한 연산을 추적해 최적화의 한계를 돌파할 수 있습니다.
컴파일과 인터프리터, 그리고 링킹
- 컴파일 언어 (C++): 소스코드 전체를 저급 언어로 한꺼번에 변환합니다. 번역(컴파일) 시간은 걸리지만 실행 속도는 압도적으로 빠릅니다.
- 인터프리터 언어 (블루프린트): 한 줄씩 실시간으로 해석하며 실행하여 유연하지만 속도는 상대적으로 느립니다. 엔진의 '네이티브화(Nativization)'는 이 노드들을 C++ 수준으로 변환하는 기술입니다.
- 목적 파일과 링킹: 컴파일로 생성된 각각의 파편화된 목적 파일(.obj)들과 엔진의 방대한 외부 라이브러리 주소를 하나로 묶어 연결하는 작업이 링킹(Linking)입니다.
- Unreal Dev Tip: 수만 개의 파일 주소를 연결하는 이 링킹 단계가 하드웨어(CPU, RAM)에 엄청난 부하를 주기 때문에 언리얼 엔진의 빌드 시간이 오래 걸리는 것입니다.
6. 추가 학습이 필요한 내용
더보기
- CPU 스케줄링과 언리얼 엔진의 Ticking 시스템: 운영체제가 멀티스레드 환경에서 자원을 할당하는 방식과 언리얼의 틱 그룹(Tick Groups)이 상호작용하는 원리.
- C++ 메모리 레이아웃과 캐시 적중률(Cache Hit): 데이터 지향 설계(Data-Oriented Design)를 기반으로 하여 CPU 캐시 미스(Cache Miss)를 최소화하고 연속된 메모리를 활용해 순회 속도를 극한으로 끌어올리는 기법.
- 가비지 컬렉션(GC)의 하드웨어적 병목: 언리얼의 UObject 생명주기와 GC 과정이 메모리 파편화 및 프레임 스파이크(Stuttering)에 미치는 영향 분석.
- VRAM 관리 및 텍스처 스트리밍 원리: 하드웨어 대역폭 한계를 극복하기 위한 엔진 레벨의 메모리 페이징 및 밉맵(Mipmap) 동적 할당 전략.
- 렌더링 파이프라인과 하드웨어 구조: 드로우 콜(Draw Call)이 CPU에서 GPU로 전달되는 명령어 버퍼(Command Buffer)의 흐름과 그래픽스 API(DirectX 11/12 등)와의 병목 지점.
'Computer Science' 카테고리의 다른 글
| [CS] CPU 성능 지표: 클럭, 코어, 스레드 (0) | 2026.03.13 |
|---|---|
| [CS] 컴퓨터 구조: CPU의 동작 원리 (0) | 2026.03.11 |
| [CS] CS의 분야 (0) | 2026.03.09 |