유니티 렌더링 최적화하기 2 – 번역

유니티 그래픽스 렌더링 최적화하기 2

(Optimizing graphics rendering in Unity games)

원문 링크

 

이전글 – 렌더링 개요

렌더링 문제의 유형 (Types of rendering problems)

렌더링에 대해서 이해해야하는 내용 중 가장 중요한 내용은 다음과 같습니다:
CPU 와 GPU는 모두, 프레임을 렌더링하기 위해서 각자가 맡은 모든 작업을 완료해야 합니다.
이러한 작업 중 하나라도 완료되는데 너무 오래걸리면, 프레임 렌더링의 지연(delay)이 발생할 수 있습니다.

렌더링 문제에는 2가지의 근본적인 원인이 있습니다.
첫 번째 문제 유형은 비효율적인 파이프라인으로 인해서 발생합니다.
비효율적인 파이프라인은 렌더링 파이프라인 중 하나 이상의 단계가 완료되는데 너무 오래걸리면서, 원활한 데이터의 흐름을 방해하기 때문에 발생합니다. 파이프라인 내의 비효율성은 병목 현상(Bottleneck)이라고 알려진 현상을 말합니다.

두 번째 문제 유형은 단순히 파이프라인에 너무 많은 데이터를 넣으려고할 때 발생합니다.
가장 효율적인 파이프라인 조차 단일 프레임에서 처리할 수 있는 데이터의 양은 한계가 있습니다.

CPU가 렌더링 작업을 수행하는데 너무 올래걸리는 문제로 인해서, 게임을 렌더링하는데 오래 걸리는 경우, 이때의 게임을 CPU바운드(CPU Bound, CPU에 묶여있는 상태)라고 합니다.
반면에, GPU가 렌더링 작업을 수행하는데 너무 올래걸리는 문제로 인해서, 게임을 렌더링하는데 오래 걸리는 경우, 이때의 게임을 GPU바운드(GPU bound, GPU에 묶여있는 상태)라고 합니다.

 

렌더링 문제 이해하기 (Understanding rendering problems)

문제를 해결하기 위해서 어떤 항목을 변경하기 전에, 프로파일링 도구를 이용해서 성능 문제의 원인을 파악하는 것이 중요합니다.
문제의 원인이 다르면 그에따른 해결책도 다릅니다. 또한, 변경사항에 따른 영향 및 효과를 측정하는 것 역시 매우 중요합니다;
성능 문제를 해결하는 과정은 균형을 잡는 과정입니다. 따라서 성능의 한 측면을 개선하면 다른 곳에 안좋은 영향을 미칠 수 있습니다.

이 글에서는 렌더링 성능 문제를 파악하고 해결하는데 도움이 되는 2가지의 도구 즉, 프로파일러와 프레임 디버거를 사용합니다.
이 도구들은 모두 유니티에 내장되어 있습니다.

 

프로파일러 창 (The Profiler window)

프로파일러를 통해서 게임이 동작하는 과정을 실시간으로 살펴볼 수 있습니다.
프로파일러를 사용해서, 메모리 사용량, 렌더링 파이프라인, 사용자 스크립트의 성능(performance)를 포함하여, 게임의 여러 측면에 대한 데이터를 확인할 수 있습니다.

프로파일러 창을 사용하는데 익숙하지 않다면, 유니티 메뉴얼 페이지에서 프로파일러 사용에 대한 내용을 확인할 수 있고, 이 강좌에서 자세한 내용을 참고할 수 있습니다.

 

프레임 디버거 (The Frame Debugger)

프레임 디버거(Frame Debugger)를 통해서, 프레임이 어떻게 렌더링되는지 단계별로 확인할 수 있습니다.
프레임 디버거를 사용해서, 매 드로우 콜 마다 그려지는 항목, 쉐이더 파이프라인 그리고 GPU에 전달되는 이벤트(event)의 순서와 같은 정보를 자세히 살펴볼 수 있습니다. 이런 정보들은 게임이 어떻게 렌더링되는지, 성능을 개선할 수 있는 부분이 어디인지를 파악하는데 도움이됩니다.

프레임 디버거를 사용하는데 익숙하지 않다면, 이 유니티 메뉴얼 페이지에서 프레임 디버거에 대한 내용을 확인할 수 있고, 이 동영상 강좌를 통해서 사용방법에 대해서 배울 수 있습니다.

 

성능 문제의 원인 파악하기 (Finding the cause of performance problems)

게임의 렌더링 퍼포먼스를 개선하기 전에, 게임이 느리게 실행되는 원인이 렌더링 문제라는 것을 확실히 해야합니다. 너무 복잡한 사용자 스크립트로 인해서 문제가 발생한 경우, 렌더링 성능의 최적화는 의미가 없습니다. 게임의 성능 문제가 렌더링에 관련된 문제인지 확실하지 않은 경우, 이 강좌를 참고하시기 바랍니다.

게임의 문제가 렌더링에 관련된 문제라는 것을 확인했다면, 게임이 CPU 바운드(CPU Bound)인지 GPU 바운드(GPU Bound)인지 파악해야 합니다. 이 두 문제는 서로 다른 해결책을 필요로 합니다. 따라서 문제를 바로 고치려 하기 전에, 문제의 원인을 이해하는 것이 중요합니다. 게임이 CPU 바운드인지 GPU바운드인지 확실하지 않은 경우, 이 강좌를 참고하시기 바랍니다.

게임의 문제가 렌더링에 관련된 문제라는 것을 확인하고, 게임이 CPU바운드인지 GPU바운드인지 여부도 파악했다면, 계속 읽어나갈 준비가 되었습니다.

 

게임이 CPU 바운드인 경우 (If our game is CPU bound)

넓은 의미에서, CPU에서 프레임을 렌더링하기 위해서 처리해야하는 작업은 3가지의 범주(카테고리, Category)로 나뉩니다:

  • 그려야하는 대상 정하기
  • GPU에서 처리해야하는 명령 준비하기
  • GPU에 명령 보내기

이 넓은 범주에는 다양한 개별 작업이 포함되어 있고, 이런 작업은 여러 개의 쓰레드(Thread)를 통해서 처리됩니다.
쓰레드를 통해서 여러 개별 작업들을 동시에 처리하는 것이 가능합니다; 한 쓰레드가 작업을 처리하는 동안, 다른 쓰레드에서 완전히 다른 작업을 처리할 수 있습니다. 이는 작업이 더 빨리 처리될 수 있다는 것을 의미합니다. 렌더링 작업이 여러 개의 개별 쓰레드를 통해서 분리되는 경우, 이를 멀티쓰레드 렌더링(Multithreaded Rendering)이라고 합니다.

유니티의 렌더링 프로세스에는 3가지 타입의 쓰레드가 포함되어 있습니다: 메인 쓰레드(Main Thread), 렌더 쓰레드(Render Thread) 그리고 작업 쓰레드(Worker Thread).
메인 쓰레드는 게임이 실행되는 동안, 렌더링 작업을 포함해서, 대부분의 CPU 작업이 처리되는 곳입니다.
렌더 쓰레드는 GPU에 명령을 보내는데 특별화된 쓰레드입니다. 각 작업 쓰레드는, 컬링(Culling), 메쉬 스키닝(Mesh Skinning)과 같은, 단일 작업을 처리합니다. 어떤 작업이 어떤 쓰레드에서 처리되는지는, 게임의 설정 및 게임이 실행되는 하드웨어의 따라서 달라집니다. 예를 들어, 타겟 하드웨어가 더 많은 CPU 코어를 가진 경우, 더 많은 작업 쓰레드가 생성될 수 있습니다. 이런 이유때문에, 타겟 하드웨어에서 게임을 프로파일링하는 것이 매우 중요합니다; 게임은 장치에 따라서 매우 다르게 실행될 수 있기 때문입니다.

멀티쓰레드 렌더링은 복잡하고 하드웨어에 의존적이기 때문에, 성능을 개선시키기 전에, 어떤 작업이 우리 게임을 CPU 바운드로 만드는지를 파악해야 합니다. 한 쓰레드에서 컬링(Culling) 작업의 처리가 너무 오래 걸리는 문제로 인해서 게임이 느리게 실행되는 경우, 다른 쓰레드에서 GPU에 명령을 보내는데 걸리는 시간을 줄이는 것은 성능에 아무런 도움이 되지 않습니다.

주의: 모든 플랫폼에서 멀티쓰레드 렌더링을 지원하는 것은 아닙니다; 글을 쓰는 시점에서 WebGL은 멀티쓰레드 렌더링을 지원하지 않습니다. 멀티쓰레드 렌더링을 지원하지 않는 플랫폼에서는, 모든 CPU의 작업이 동일한 쓰레드에서 처리됩니다. 이런 플랫폼에서 CPU 바운드인 경우, CPU 작업의 최적화를 통해서 CPU 성능을 향상시킬 수 있습니다. 게임이 직면한 문제가 이 경우라면, 다음 섹션을 읽고 게임에 가장 적합한 최적화가 무엇일지 고민해봐야 합니다.

 

내용 끝까지 읽어주셔서 감사합니다.

배너 클릭은 저에게 많은 힘이 됩니다.

감사합니다 🙂

 

다음글 – 그래픽 작업

RonnieJ

프리랜서 IT강사로 활동하고 있습니다. 게임 개발, 웹 개발, 1인 기업, 독서, 책쓰기에 관심이 많습니다.

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다