03/06 본캠프 #50

guno park·2024년 3월 6일
1

본캠프

목록 보기
50/77

유니티 최적화

  • 최적화 : 다양한 의미가 있겠지만 주된 목적은 렉, 버그없이 사용자들이 불편하지 않도록 하는 작업

서론

  1. 프로파일링
  2. 가비지 컬렉터 - 기술면접 단골 질문
  3. 스크립트
  4. 에셋 임포트
  5. 그래픽스 및 GPU 최적화

최적화의 기준 지표 - Stats
주의 깊게 살펴볼 것 -
1.FPS
2. Batches - Cpu가 GPU에게 어떠한 물체를 그리라고 요청하는 것, 모바일의 경우 100개 정도가 상한선 SetPass Call

FBS와 Batches는 반비례 관계 => 즉, Batch를 줄이고 FPS를 높여야함.

프로파일링

  • Window -> Analysis -> Profiler

  • 보통 CPU 사용량을 봄 그래프가 튀면 튈수록 안좋다.

  • 에디터 루프는 에디터에서 나오는 사용 -> 빌드 시에는 연관 X => 빌드하는게 프레임이 더 나올수 있다.

  • Deep profile 체크하면 모든 스크립트가 프로파일링됨.
    이렇게 하면 어느 함수에서 퍼포먼스가 많이 소요되는지까지 자세하게 알 수 있음.
    장점 - 자세하다.
    단점 - 오버헤드가 매우 커서 메모리를 많이 잡아먹음. 대형 게임에서 사용 시 메모리 부족 현상이 발생할 수도 있음.

  • 수동으로 프로파일링 =>Profiler.BeginSample, endSample 두 메서드 사이의 코드블럭을 분석

가비지 컬렉터

  • 미사용 힙 메모리를 자동으로 파악하고 해제하는 프로세스
    주소 체계를 사용하는 참조형(string, Class 등등)은 힙 영역에 해당
    모든 객체를 추적해서 사용하지 않는 객체의 메모리를 해제함.
    가비지 컬렉터에게 먹이를 주지 않는 것이 중요하다.

스크립트

  • Find를 사용하는 것을 자제

  • GetComponent 반복적인 사용 금지.
    일종의 탐색이기 때문에 인스펙터 창으로 할당이 불가능한 경우 Awake나 Start에서 변수에 미리 받아놓고 사용.
    특히 Update문에서 주의

  • 하이어라키의 복잡성을 줄여라.
    조그마한 transform 변화에도 하위의 모든 계층에 대한 계산을 다시하기때문 가급적 transform변화가 있는 오브젝트를 별도로 관리하는 것이 좋음.

  • 빈 Unity 이벤트 함수는 삭제
    start, update를 사용하지 않는다면 그냥 지워버리기

  • 박싱과 언박싱
    박싱 -> 값 => 참조 / 언박싱 -> 참조 => 값
    ex) int,float => object : 박싱 반대는 언박싱
    Dicionary의 키로 Enum 타입을 사용하면 박싱이 일어남. =>net4.x부터는 안일어난다고 함

  • 클래스나 리스트 반복 재할당 금지
    Update문이나 반복문 내의클래스와 리스트 등 참조 형식의 변수들을 재할당 할 경우 GC의 먹이가 됨.
    반복 전에 미리 할당을 받아놓고재사용
    특히 리스트는 clear를 활용

  • 코루틴 yield new return 할 때 new 반복생성 금지 => 아는 내용

  • 무분별한 Linq 사용은 자제
    로직을 직접 제어 못하기 때문에 오용 시 오히려 비효율
    유니티에서 사용 시 성능이 저하되고 IOS에서 안먹히는 버그가 있음

  • List 사이즈 초기화
    List의 사이즈를 넘어서 Add가 될 경우 기존 할당보다 두배의 할당을 하기 때문에 순간적인 성능 저하 발생
    사이즈를 추측할 수 있다면 미리 크게 할당을 해놓고 사용하는 것이 더 효율적일 수 있음
    Defalut의 사이즈는 4

  • string 연산 최적화
    string의 += 연산은 객체 할당이 일어나기 때문에 연속적으로 사용 시 GC의 먹이
    문자열 변경이 자주 일어날 경우 StringBuilder 사용

  • 클래스와 구조체
    클래스는 참조타입, 구조체는 값타입
    몇 개 안되는 변수들로 이루어진 간단한 타입들은 클래스가 아닌 구조체로 만들어서 불필요한 힙 할당을 줄이도록 하자

에셋 임포트

pot 텍스쳐

가로/세로 크기가 2의 승수
pot가 아닌 텍스쳐들은 가장 가까운 사이즈의 2의 승수를 찾아서 텍스쳐를 복사하기 때문에 이론상 메모리에 2개의 텍스쳐가 올라가게 된다.
모바일 게임에서는 반드시 중요한 부분

스프라이트 아틀라스

여러 텍스쳐를 단일로 결합
프로젝트 세팅에서 스프라이트 패커를 설정해주어야됨
사용시 Batches가 확 줄어듬

그래픽스 및 GPU 최적화

라이팅 맵 - 빛 연산 정보를 텍스처 형태로 저장하는 기법

Bake 하는게 그건가봄.
움직이지않는 오브젝트에 한해서 Static을 체크해놔야 한다.

카메라 Cliping Planes

far를 줄여서 렌더링하는 범위를 줄이자.

오쿨루전 컬링

눈에 보이지 않는 범위(다른 오브젝트에 가려졌거나 거리가 먼)를 렌더링 하지 않음.
오브젝트에 static 속성과 오쿨루젼 속성 체크

기술면접 질문

질문 : float와 int의 표현 가능한 수의 범위가 다른 이유는 무엇인가요?

float과 int를 표현하기 위한 bit 수는 동일하지만 float은 실수, int는 정수를 표현하기 때문에 bit를 사용하는 용도가 다릅니다. 1bit은 부호를 나타내는 것이므로 동일하지만, int는 31bit을 이용해서 수를 나타내고, float은 31bit 중 8bit는 지수를, 23bit는 가수를 나타내는데 사용되기 때문입니다.

요약하자면, 'int'와 'float'는 같은 비트 수를 사용할지라도 그들이 이 비트를 다르게 사용함으로써 서로 다른 수의 범위를 표현할 수 있습니다. 'float'는 광범위한 범위의 수를 표현할 수 있지만 정밀도가 떨어지고, 'int'는 범위는 좁지만 정밀도가 높습니다.

0개의 댓글