Dev/Unity

[Unity] 병목 - 유니티 그래픽스 최적화 스타트업 정리

_cpdm_ 2025. 2. 10. 13:47
반응형

 

 


 

병목

최적화를 수행하기 위해 다양한 방법들이 있겠으나, 선행되어야 할 것이 병목을 탐지하는 것

  • 일반적으로 수행되는 최적화 목록
    • Mesh의 Vertex 줄이기
    • Texture 사이즈 줄이기
    • Shader를 가볍게
    • Draw Call 줄이기
    • Logic 최적화
    • 물리 연산 줄이기

 

Bottle neck, 병목

  • 전체 프로세스가 갑자기 느려지거나 막혀서 정지하는 부분
  • 그래서 어떤 부분에서 병목현상이 일어나는지를 알기위해 프로파일링이 중요하다.

 


Profiling

  • 병목 지점을 찾는 과정
  • 원인을 찾아서 최적화를 수행한다.



FPS와 Frame Time

  • Frame Time 
    • 한 Frame을 처리하는 데 걸리는 시간 -> 프로파일링 할 때 Frame Time으로 하는 것이 좋다.
    • 일반적으로 Frame Time은 ms 단위로 측정
  • Editor의 Game 뷰 좌상단의 Stats를 누르면 FPS와 Frame Time 확인 가능
    • Editor에서의 성능 측정은 큰 의미가 없기 때문에 실제 디바아ㅣ스에서 측정해야 함.
  • Time.unscaledDeltaTime 
    • 한 Frame 처리를 위한 시간



구간 측정

  • 성능을 측정할 때 중요한 포인트?
    • 각 Frame을 렌더링하는데 시간이 얼마나 걸리는지
  • FPS로만 측정하기 보다는 어디에서 얼마나 시간이 걸렸는지를 알기 위해 Frame Time으로 측정하는 것이 좋다.



선형 측정

  • FPS 값은 비선형적인 변화를 보이기 때문에 성능 저하가 일정하게 일어나고 있는지 판단하기 어려움
  • 예시
    • 오브젝트 하나를 추가할 때마다 FPS가 떨어지는 것을 측정했는데 변화가 90 -> 45 -> 30 이라고 가정
      • 일정하게 변화한 것으로 보이는 가? 
    • 1 Object = 90 FPS = 1000/90.0 = 11.1ms
    • 2 Objects = 45 FPS = 1000/45.0 = 22.2ms
    • 3 Objects = 30 FPS = 1000/30.0 = 33.3ms
      • 실제로는 일정하게 변화한 것이 맞다.
    • 따라서 Frame Time으로 측정해야 변화량을 제대로 측정할 수 있다는 결론



측정 시나리오

  • 측정은 여러번 측정 후 평균 값을 계산
  • 여러 Scene, 여러 상황에서 다양하게 측정하는 것이 좋음
  • Deferred Randering Path는 기본적으로 대역폭 요구 성능이 크다.
  • 후처리 효과들도 기본 비용이 크다.(Bloom 등.)



Target Frame Rate

  • 모바일 디바이스가 쓰로틀링에 걸리지 않게 강제로 최대 FPS를 설정할 수 있음
  • Application 시작 시 Application.targetFrameRate = 40; 을 설정하면 40FPS로 설정.



VSync ( 수직 동기화 )

  • 모니터 주파수와 렌더링 퍼포먼스를 맞춰 Tearing 현상(물결치는현상)을 방지하는 역할
    • Tearing
      • 모니터는 화면 갱신 주파수에 한계가 있음
      • 이를 넘는 신호를 입력하면 화면이 물결치거나 찢어지는 듯한 현상 -> Tearing
      • Back Buffer가 아직 렌더링 되고 있는 동안 Front Buffer와의 전환이 이루어져 현 화면과 이전 화면이 섞여서 나타나는 현상
      • 이를 방지하기 위한 것이 VSync로, 모니터의 주파수에 맞게 렌더링 퍼포먼스를 조절해준다
  • targetFrameRate를 높게 설정했음에도 60FPS를 넘지 못한다면 VSync를 의심
  • 성능 측정 시에는 꺼주는 것이 좋음
    • Edit > Project Settings > Quality > Don't Sync



Throttling을 고려한 측정

  • 성능 프로파일링 시 Throttling을 고려해야 한다.
  • 고려 사항
    • 디바이스가 얼마나 빠르게 Throttling 상태로 진입하고, 얼마나 성능이 떨어지는 지
    • 발열 관리
    • 배터리는 항상 100%
    • 측정 후 다음 측정까지 5분 대기
    • 쿨링



CPU Bound vs GPU Bound

  • 병목이 CPU에서 발생하는 지 GPU에서 발생하는 지 확인이 필요
  • CPU와 GPU는 병렬처리 방식이다.
    • CPU는 명령을 주고 계속 자기 일을 처리한다.
    • 한 Frame에서 CPU는 일처리를 모두 마쳤지만, GPU는 받은 작업들을 순차 처리 중인데 아직 끝나지 않았다면 CPU는 기다리게 된다.
      • 이를 GPU 바운드 상태라고 하고 GPU의 작업을 줄ㄹ여야 한닫.
    • 반대로 GPU가 대기하고 CPU가 연산 중인 상황을 CPU 바운드라고 하며 CPU 작업을 줄여줘야 한다.

 


 

병목 측정 및 탐지



Unity Profilier 

  • 유니티에서 제공하는 프로파일러
  • Window > Analysis > Profiler 
  • 프로파일러 연결은 개발 빌드로 연결해야하며 측정 부하가 포함된다. ( = 릴리즈 빌드와 차이가 있음 )
    • 에디터 측정은 의미 없다.
  • 단, GPU 병목은 내장 프로파일러로는 디테일하게 파악이 힘들다.
    • Android는 Graphics API가 Vulkan일 경우 지원 가능.
    • Snapdragon 칩셋을 사용하는 디바이스는 Qualcomm에서 제공하는 전용툴로 GPU 프로파일링 툴인 Snapdragon Profiler 사용
    • IOS는 XCode에서 제공하는 GPU FrameDebugger 이용



Fillrate

  • 그래픽카드가 1초에 스크린에 렌더링할 수 있는 픽셀의 수
  • 게임 렌더링에서는 픽셀 처리에 대한 부담을 모두 포함한 개념
    • 필레이트 = 화면 픽셀 수 x 프래그먼트 쉐이더 복잡도 x 오버드로우
  • 픽셀이 많거나 프래그먼트 쉐이더가 너무 복잡하면 Rasterizer 단계에서 병목이 발생
    -> 이때 필레이트가 병목이 되었다고 표현 (필레이트 바운드)
  • 디스플레이 해상도를 변경했을 때 성능이 눈에 띄게 좋아진다면 해상도(렌더링 해야하는 픽셀 수)가 원인으로 필레이트 병목을 강하게 의심할 수 있다.
    • 해상도 설정
      • Edit > Project Settings > Player > Resolution Scaling 항목 수정
      • Mode는 기본적으로 Disabled, Fixed DPI로 변경하여 DPI에 맞게 자동 조정 가능
        (DPI가 낮을 수록 해상도가 낮게 조절)
      • Screen.SetResolution() 활용 



오버드로우

  • 화면에 렌더링 되는 픽셀이 여러 번 덧그려지는 현상
    (채워진 픽셀을 또 다른 Object를 렌더링하면서 다시 그리면 오버드로우라고 함)
  • ZBuffer가 오버드로우 방지를 도와준다.
    • Camera와의 거리 순으로 정렬하여 앞부터 그리므로 뒤에 가려지는 부분은 안그린다.
  • 투명 / 불투명 오브젝트
    • 불투명 오브젝트는 카메라 앞에서 뒤로 정렬.
      • 뒤에 있는 오브젝트의 가려지는 픽셀은 렌더링을 건너 뛴다.
    • 투명 오브젝트는 카메라 뒤에서 앞으로 정렬
      • 모든 픽셀에서 오버드로우가 발생.
  • 파티클
    • 파티클의 밀도가 높을 수록 오버드로우가 많아진다.



포스트 프로세싱

  • Fragment 쉐이더가 무거워지는 요인 중 하나이다.
  • 포스트 프로세싱이 병목의 원인이라면 해상도를 줄이면 해결된다.
  • 포스트 프로세싱 종류별로 성능 비용이 다르다.
    • Color Grading은 모바일에서도 부담이 없다.
    • Bloom까지도 최근 디바이스의 성능이 좋아지면서 사용된다.
    • DOF는 모바일에 적용하기에는 성능 부담이 크기 때문에 컷씬이나 로비등에서 사용한다.



Upscaling Sampling

  • 해상도를 줄이면 성능을 올릴 순 있지만, 유저가 알아보기 쉽다.
  • UI의 해상도를 유지하고 3D 씬만 낮은 해상도로하여 트릭을 주는 것이 업스케일링.
  • 구현 순서
    • 저해상도 Render Texture 생성
    • 3D 씬을 Render Texture에 렌더링
    • Render Texture를 업스케일링 해서 현재 Back Buffer에 렌더링
    • Overlay UI 렌더링
  • 핵심은 전체 해상도를 줄이는 것이 아니라는 것



Polygon

  • 폴리곤 수가 많다 = 버텍스 수가 많다 -> Geometry 부분에서 병목이 생긴다.
    • Vertex Shader를 많이 수행한다.
  • 폴리곤 수를 줄였을 때 성능을 체크해본다.
  • LOD ( Level of Detail)
    • 디테일에 단계를 나누는 것
    • 가까이 있는 건 자세히 그리고, 카메라에서 멀리 있는 건 디테일을 떨어뜨린다.
    • 이를 바탕으로 vertex 수를 줄인다.
    • Edit > Project Settings > Quality > Other 에서 LOD Bias를 조절할 수 있다.



Texutre

  • 전체 텍스쳐의 해상도를 조절해보면서 병목 원인인지 아닌지 확인할 수 있다.
  • 텍스쳐 해상도 조절
    • Edit > Project Settings > Quality > Rendering 섹션

 


 

 

cpdm

 

choppadontbiteme.tistory.com

 

반응형