KoreanFoodie's Study

[언리얼] 언리얼 최적화 프로파일링 : 멀티 플랫폼을 위한 최적화 드라이브 (언리얼 서밋 2022) 요약 본문

Game Dev/Unreal C++ : Dev Log

[언리얼] 언리얼 최적화 프로파일링 : 멀티 플랫폼을 위한 최적화 드라이브 (언리얼 서밋 2022) 요약

GoldGiver 2023. 5. 14. 21:07

[언리얼] 어떤 개념 : 어떻게 하기

핵심 :

1.
2.
3.

언리얼 서밋 온라인 2022 를 훑어 보면서, 최적화 및 프로파일링과 관련한 내용이 있어 기록차 요약해 보려 합니다.

현재 개발 중인 버전이 언리얼5 가 아니라서 아쉬운 부분은 있지만... 일단 알아두면 많은 도움이 되겠죠 😅

언리얼 서밋 온라인 2022 를 보며 내용을 정리했으니, 궁금하신 분은 풀 영상을 보시길 바랍니다! 😄

 

Hitching 이 언제 발생하는지 파악하여 어떤 부분에서 병목현상이 발생하는지 파악해야 한다. 카트라이더의 경우 GameThread 에서 병목이 발생하여 이를 집중적으로 다루었다고 함.

강의에서는 다루지 않았지만... RenderThread 의 경우, PSO 캐시를 통해 최적화를 진행하였다고 한다. 관련 내용은 공식 문서에 있음! 4.27 버전

 

위와 같이 파라미터를 세팅하여, Unreal Insight 를 활용하면 된다! 언리얼 인사이트에 관한 공식 문서를 참고하여, 언리얼 인사이트를 활성화하자.

127.0.0.1 -log -tracehost=127.0.0.1 -NetTrace=1 -loadtimetrace -statnamedevents -trace=cpu,fram,loadtime

 

언리얼 인사이트는 위와 같은 내용들에 대한 정보를 제공해 준다..!

Nullrhi 를 이용하면 렌더링 부하 없이 병목을 테스트해볼 수 있다! 😄 Tick 규모가 클 수록, 효과가 더욱 클 것이다!

 

1번의 경우, 객체의 라이프사이클을 객체의 용도에 맞게 쓰는 것이며,

2번은 블루프린트 네이티브화이며,

3번은 L1 캐시를 사용하거나, 멀티쓰레딩을 응용하는 것을 의미한다.

 

즉, 컴포넌트 패턴을 활용하여, 각 컨포넌트를 꼭 필요할 때만 붙이겠다는 뜻이다!

 

실제 예제를 보자.

카트라이더에서는, 폰에 CreateDefaultSubobject 를 마구 사용하지 않고, 액터의 Role 에 따라, 각각 다른 액터 컴포넌트를 갖도록 구현하였다.

 

즉, 위처럼 꼭 필요한 액터 컴포넌트만 붙여주는 방식이다!

 

Cosmetic layer 를 걷어내면, 데디케이트 서버에 대한 부하를 줄일 수 있다! 

 

구글에서 최적화 검색을 하면 Tick 관련 이야기가 많이 나온다. 이때, DumpTicks 치트를 이용해 틱을 사용하는 객체들을 체크할 수 있다. 특히 Timeline 을 다른 방식으로 구현하는 게 좋다.

 

회전의 경우, 애니메이션에서 처리하기보다는, Material 에서 Vertex Shader 로 Rotation 을 해주면, 낮은 비용으로 구현할 수 있다.

 

위에서, 같은 함수를 4번 불러줄때의 결과를 보면, 첫 시도가 제일 많이 걸리는 것을 확인할 수 있다.

이는 L1 캐시를 활용하기 때문인데, 같은 함수를 모아서 불러주면 L1 캐시 적중률이 올라가 같은 함수를 가볍게 호출하여 처리해 줄 수 있게 된다!

 

프로젝트마다 뭐가 중요한지를 정리해야 한다.

 

화면에 플레이어가 많이 보일 경우, Skeletal Mesh 최적화가 필요하다. LOD 의 경우 객체와 카메라 사이의 거리에 따라 좌우되는데, Device Profile 을 보고 세부적인 Tuning 을 해 주어야 한다.

 

그게 위 내용이다... 요즘은 확실히 모듈형 개발이 트렌드인것 같다 😅

 

애니메이션이 있으면 틱을 비활성화 할 수 없으므로, 언제 틱을 활성화할지에 대한 Enum 값을 설정하여 옵션을 조절했다. 즉, 렌더될때만 틱이 돌아가도록 설정한 것이다.

 

그런데, 틱을 끄면 LOD 가 갱신이 안되는데... 이를 Significant Manager 에 등록해서 별도로 관리해주면, Tick 이 Aggregate 되는 효과도 있었다.

 

추천 패키지도 있다 😉

 

멀티 쓰레딩이 최적화에 정말 좋다고 한다.

 

다만 멀티 쓰레딩을 적용하려면, 옵션을 확인해 주어야 한다.

틱 그룹이 다르면 Parallel Update 를 블락할 수 있어서... (멀티 쓰레딩이 안됨) 해당 내용을 확인해야 한다.

 

멀티 쓰레드 에서는 락이 항상 걱정되는 부분인데, 카트라이더는 TickGroup 을 이용해 이 문제를 회피했다고 한다. 

즉, 필요한 로직마다, 필요한 Tick Group 에서 해당 로직이 처리되도록 했다는 것이다! 완전 똑똑하다.. 😮

 

머신 러닝을 통해 다음 캐릭터의 움직임을 예측하도록 학습시키고 있는데... 이때 이를 병렬 처리하여 메인 쓰레드에 부하를 줄였다고 한다.

 

멀티코어 점수가 매우 크므로(오른쪽 그림), 멀티 쓰레딩을 활용하는 것을 추천한다고 한다. 이는 발열 문제에도 긍정적인 영향을 미친다.

 

UI 최적화도 매우 중요하다.

 

Invalidation box 에 담긴 위젯은, prepass 시 paint 되지 않는다. 이에 슬레이트의 렌더링 속도를 올려줄 수 있다고 한다. 자손의 모든 위젯을 검사하므로, Depth 에 따라 잘 감싸주어야 한다.

위젯 리플렉터의 인벨리데이션 디버깅을 이용해 UI 의 부하를 확인할 수 있다.

 

추가 팁이다..!

 

감사합니다..

 

위와 같이, 전체 화면을 UI 가 덮은 경우에는 어떤 최적화를 할 수 있을까?

 

바로,, 뒤에 있는 오브젝트를 렌더할 필요 없다는 점이다!

 

로딩 페이지에서 로딩 및 GC 를 하자! 이때, 레벨을 로드하면 애셋이 GC 되므로, GC 되지 않도록 처리해 주는 것이 중요하다.

 

최대한 움직이지 않아도 되는 녀석은 Overlap 을 끄고, 카트바디에 대해서만 Overlap 을 활성화했다.

 

위의 WhiteList 에서 언급했듯, Cosmetic Layer 을 걷어내었으므로, 서버에서는 Validation 과 패킷 처리만 해주면 되었다. 이때, 패킷 처리하는 부분에 부하가 많았는데... Client Agent 에서 AI 관련 항목을 계산하기보다, 서버에서 계산해서 결과값을 보내주기만 하는 식으로 구현했다.

 

네트워크 최적화를 위해, Replication 변수에 대한 최적화를 진행함. 사용하지 않는 변수는 Disable 시키고, 매 프레임마다 변경이 일어나는 변수가 Replication 되므로, 서버에서 매 프레임 Dirty Check 후 replication 하도록 변경했다.

 

TArray/FString/FString 의 경우에는 부하가 크므로, 전송 시 유의하자.

 

위치에 상관없이 폰이 다른 폰에게 영향을 끼칠 수 있었는데...

 

그런데, 8명의 플레이어가 있다고 할 때, 모든 플레이어에 대해 100프레임으로 동기화를 해주면 네트워크 대역폭을 초과하게 된다!

따라서, 가까운 유저에 대해서는 고빈도로 Replication 되도록, 멀리 있으면 더 낮은 빈도로 Replication 되도록 NetCull 관련 변수를 설정했다. 가까운 곳에 있으면 ALowLatencyActor 를 만들어 주고, 거리가 멀어지면 자동 소멸하게 만드는 식인 것 같다 😅

 

패킷 전송 빈도가 높은 경우, 오차 범위가 10자리 이상에서 문제가 나는 경우는 거의 없기 때문에... 10자리까지로 자릿수를 줄이는 등의 방식으로 전송 대역폭을 최적화할 수 있었음!

 

좋은 내용 공유해 주셔서 감사합니다!

 

카트라이더 드리프트 화이팅!

 

[카트라이더: 드리프트] No limits, all drift!

PC-콘솔-모바일 글로벌 멀티 크로스 플레이 지원 차세대 카트라이더

kartdrift.nexon.com

 

참고 : 언리얼 공식 문서
Comments