일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- CTF
- level design
- gameplay effect
- 언리얼 엔진
- Multiplay
- Unreal Engine
- listen server
- 유니티
- C++
- local prediction
- ability task
- Replication
- 게임개발
- 보안
- MAC
- Aegis
- UI
- 게임 개발
- gas
- gameplay tag
- widget
- animation
- stride
- attribute
- 언리얼엔진
- photon fusion2
- unity
- rpc
- os
- gameplay ability system
- Today
- Total
Replicated
[Teck Interview] C++, 동기, 비동기, 블로킹, 논블로킹, 게임 최적화 본문
포인터와 참조의 차이
항목 | 포인터 (Pointer) | 참조 (Reference) |
선언 방법 | int* p = &a; | int& r = a; |
널(null) 가능 | 가능 (p = nullptr;) | 불가능 (항상 유효한 참조여야 함) |
초기화 여부 | 나중에 초기화 가능 | 선언 시 반드시 초기화 필요 |
재지정 가능 여부 | 다른 객체를 가리킬 수 있음 | 한 번 정해지면 다른 객체 참조 불가 |
간접 접근 | *p, p-> | 직접 변수처럼 사용 (r) |
메모리 주소 연산 | 가능 (&p, p++) | 제한적 (&r은 실제 객체 주소) |
virtual과 override
항목 | virtual | override |
정의 위치 | 기본 클래스(Base class) | 파생 클래스(Derived class) |
목적 | 함수가 파생 클래스에서 오버라이드 가능하게 함 | 해당 함수가 기본 클래스의 가상 함수 재정의임을 명시 |
오류 방지 여부 | X (컴파일러가 재정의인지 확인 못함) | O (재정의가 아니면 컴파일 에러) |
사용 여부 | 최소 한 번 필요 (기반 클래스에서) | 권장 (실수 방지에 유리) |
Unity에서 GC 최소화 방법
- Obejct Pooling
Unreal Engine에서 UObject와 AActor의 차이점
항목 | UObject | AActor |
기본 클래스 | 모든 언리얼 클래스의 기본 클래스 | AActor는 UObject를 기반으로 한 UObject의 하위 클래스 |
씬에 존재 여부 | 월드/씬에 존재하지 않음 | 월드(레벨)에 배치 가능 |
트랜스폼(위치, 회전, 스케일) | 없음 | 있음 (RootComponent 기준) |
Tick 지원 여부 | 직접적으로 없음 (별도 처리 필요) | Tick() 함수로 매 프레임 처리 가능 |
컴포넌트 추가 | 불가 | 가능 (UActorComponent, SceneComponent 등) |
생성 방식 | NewObject<UYourObject>() | GetWorld()->SpawnActor<AYourActor>() |
가비지 컬렉션 | 지원 | 지원 |
예시 용도 | 데이터 구조, 비동기 작업, 관리용 객체 | 캐릭터, 아이템, 환경 오브젝트 등 |
동기 vs 비동기 처리의 차이와 사용 예시
항목 | 동기(Synchronous) | 비동기(Asynchronous) |
처리 방식 | 작업이 순차적으로 진행됨 | 작업이 병렬적으로, 또는 콜백/이벤트 기반으로 진행됨 |
다음 작업 시작 시점 | 이전 작업이 완전히 끝난 후에 가능 | 이전 작업의 완료를 기다리지 않고 바로 다음 작업 시작 가능 |
코드 흐름 | 간단하고 예측 가능 | 복잡한 흐름, 콜백/이벤트/프라미스 필요 |
효율성 | 간단한 작업에 적합 | 네트워크, I/O, 멀티태스킹에 적합 |
비동기 처리 예
- 리소스 로딩, 서버 요청/응답 등
동기/비동기 - 블로킹/논블로킹
동기 vs 비동기
- 작업의 흐름 제어 방식
- 동기는 호출한 함수가 끝날 때까지 기다림
- 비동기는 기다리지 않고 나중에 알려줌
블로킹 vs 논블로킹
- 리소스 상태에 따라 호출자가 멈추는지 여부
- 블로킹은 결과를 기다리는 동안 CPU를 점유하며 멈춤
- 논블로킹은 작업이 완료되지 않았어도 즉시 리턴 (기다릴 상황이 있었지만, 기다리지 않고 즉시 돌아옴)
동기 + 논블로킹
- 가능함. 그냥 당장 결과 안나오면 실패해도 리턴하라..
- 소켓을 이렇게 열기도 가능
비동기 + 블로킹
- 가능함
- 비동기는 작업을 별도 흐름으로 실행하는 거고 블로킹은 호출자가 결과를 기다리는 거임
- 작업은 딴 데서 하는데, 꼭 필요하니까 끝날 때까지 기다린다,
작업 흐름이랑 기다리는 거랑 좀 다른 관점임
예시
UAssetManager::GetStreamableManager().RequestAsyncLoad(WeaponAsset, FStreamableDelegate::CreateLambda([&]() {
UE_LOG(LogTemp, Log, TEXT("무기 로드 완료"));
}));
비동기로 로드. 이건 비동기 논블로킹
UAssetManager::GetStreamableManager().RequestSyncLoad(WeaponAsset);
이거 내부적으로 비동기 로딩하는데 블로킹함. 사실상 비동기 + 블로킹
FPS를 유지하기 위한 최적화 방법은 어떤 것이 있나?
일단 프로파일링해서 병목 지점 찾기
렌더링 최적화 (GPU)
- LOD -> 멀리있는 모델은 폴리곤 줄임
- Occlusion Culling -> 안보이는 객체는 렌더 안 함
- Instancing -> 같은 메시에 대한 Draw Call 줄이기
- Static Lighting -> 고정 조명은 Lightmap으로 베이크
- Shadow Distance -> 그림자 렌더 범위 줄이기
- Post Process 줄이기 -> 고비용 효과 제한
틱 최적화 (CPU)
- 불필요한 틱 안쓰기
- 틱 간격 늘리기 (TickInterval)
- Condition Tick
- Actor 수 줄이기
- 로직 분리 (타이머, 이벤트로 분산)
메모리와 GC(가비지 컬렉션)
- UObject 수 줄이기
- Short-lived 객체 줄이기
- 오브젝트 풀링
- Manual GC 관리 (특정 상황에선 직접 가비지 컬렉션 호출)
애니메이션 최적화
- Animation LOD .. 가까운 캐릭터만 풀 애니메이션 처리
- Update Rate Optimization
- Pose Caching .. 중복 계산 줄이기
- Blend 줄이기 .. 복잡한 블렌드 스페이스/노드 제한
AI/네비게이션 최적화
- AI 틱 줄이기
- Path Finding 빈도 제한
- EQS 빈도 제한
레벨 스트리밍, 로딩 최적화
- 레벨 분할
- 비동기 로딩 (LoadAsync, StreamableManager)
- 필요 리소스만 로딩
UI 최적화
- 틱 없는 UI (필요한 거만 사용)
- Visibility 제어 -> 안보이는 UI는 SetVisibility(ESlateVisibility::Collapsed); => 안보이고 공간도 차지 안함
- Retainer 사용
* Retainer
- 자식 위젯을 캐시에 그려서 성능을 향상시키는 위젯
- 자식 위젯들을 한 번 렌더링한 뒤 텍스처로 저장해두고 매 프레임마다 다시 그리지 않고 저장된 결과만 표시
-> 렌더링 비용 절감
- 매우 자주 변하는 UI는 텍스처 캐시 생성 비용 때문에 오히려 역효과
'지식' 카테고리의 다른 글
[Teck Interview] 네트워크 및 멀티플레이 (0) | 2025.05.28 |
---|---|
[Teck Interview] 게임 클라이언트 구조, MVC, MVVM, 상태 동기화, 씬 전환 메모리 최적화 (0) | 2025.05.28 |
[Math] 외적 (0) | 2025.05.28 |
[Math] 내적 (0) | 2025.05.28 |
[C++] 상속 시 생성자 탐구 (0) | 2025.05.27 |