프로파일링
Practical Guide to Optimization for Mobiles

최적화

PC와 마찬가지로 iOS 및 Android는 다양한 수준의 성능을 가진 장치가 있습니다. 다른 기기보다 10배의 렌더링이 강력한 기기는 쉽게 찾을 수 있을 정도입니다. 스케일링을 하는 쉬운 방법은 :

  1. 기준선 설정에서 문제없이 실행할 수 있는가를 확인한다
  2. 높은 퍼포먼스가 허용되는 설정에서는 보기 좋은 외형을 준다 :
  3. 해상도
  4. 포스트 프로세싱
    • MSAA
  5. Anisotropy(이방성)
  6. 쉐이더
  7. Fx / 파티클 밀도의 활성화 / 비활성화

GPU의 포커스

그래픽 성능은 필레이트(Fillrate), 픽셀 수 및 지오메트리의 복잡성(정점 카운트)에 의해 제한됩니다. 이들 3개 모두 렌더러를 컬링하는 방법을 찾아내면 줄일 수 있습니다. 오클루전 컬링이 여기에 도움이 될 수 있습니다. Unity는 자동으로 뷰 Frustum 밖에 있는 오브젝트를 컬링합니다.

모바일에서는 필레이트 제한(필레이트 = 화면 픽셀 수 x 쉐이더 복잡성 x 오버 드로우)이 있으며, 복잡한 쉐이더가 대부분의 문제의 원인 입니다. 따라서 Unity에 포함되는 쉐이더를 사용하거나 직접 디자인 할 때는 가능한 한 단순하게 합니다. 만약 가능하다면 픽셀 쉐이더를 정점 쉐이더로 이행하여 심플하게 합니다.

Quality Settings에서 Texture Quality를 내리는 것으로 게임이 빨라지는 경우, 메모리 대역폭에 의해 제한되어 있을 가능성이 높습니다. 텍스처 압축, 밉맵 사용, 텍스처 크기 줄이기 등을 합니다.

LOD(Level of Detail) - 오브젝트를 심플하게 만들거나 완전히 멀어지면 이들을 없애도록 합니다.

Good practice

모바일 GPU는 발열, 사용 전력, 소리의 크기등에 큰 제한이 있습니다. 따라서 데스크탑 부품에 비해 모바일 GPU는 대역폭이 적고, ALU 성능이 낮고, 텍스처링 파워가 떨어집니다. GPU의 아키텍쳐는 가능한 한 작은 대역폭으로 소량의 전력을 사용하도록 최적화되어 있습니다.

Unity는 OpenGL ES 2.0에 최적화되어 있고, GLSL ES(HLSL과 유사한) 쉐이딩 언어를 사용합니다. 내장 쉐이더는 대부분 HLSL(Cg라고도 알려진)​​로 작성되어 있습니다. 이것은 모바일 플랫폼에서는 GLSL ES로 크로스 컴파일됩니다. 직접 GLSL을 작성할 수도 있지만, GLSL->HLSL 변환 도구가 현재 없기 때문에 OpenGL 소프트웨어 플랫폼이 제한됩니다 (예 : 모바일 및 Mac). HLSL에서 float/half/fixed 형을 사용하면 GLSL ES에서는 highp/mediump/lowp 정밀 표현됩니다.

좋은 연습을 위한 체크리스트를 보여줍니다 :

  1. 메테리얼 수를 가능한 한 적게 합니다. 따라서 Unity의 배칭이 쉬워집니다.
  2. 개별 텍스처보다 텍스처 아틀라스(서브 이미지가 포함된 큰 이미지)를 사용한다. 이 편이 로드가 빠르고, 상태 변경이 적으며, 배칭과 친화성이 있습니다.
  3. 텍스처 아틀라스와 공유 메테리얼을 사용하는 경우 Renderer.sharedMaterialRenderer.material 대신 사용합니다.
  4. Forward rendering 픽셀 라이트는 부하가 높습니다.
  5. 가능한 한 실시간 라이트 대신 라이트 매핑을 사용하십시오.
  6. quality settings에서 pixel light count를 조정합니다. 요컨대 지향성 라이트만이 픽셀 단위여야 하며, 그 외에는 모두 정점 단위로 해야 합니다. 이것은 당연히 게임에 따라 어떻게 해야 할지 결정됩니다.
  7. Quality Settings의 Render Mode of Lights와 함께 실험하여 올바른 우선 순위가 되도록 합니다.
  8. 컷아웃(알파 테스트) 쉐이더는 정말 필요한 경우에만 합니다.
  9. 화면에 사용하는 투명(알파 블렌딩) 적용범위를 최소화합니다.
  10. 여러 라이트가 특정 오브젝트를 비추는 상황을 미리 피합니다.
  11. 쉐이더 경로의 전체 숫자를 줄입니다(그림자, 픽셀 라이트, 반사).
  12. 렌더링 순서는 중요합니다. 일반적으로 :
  13. 완전히 불투명한 오브젝트는 대체로 앞에서 뒤쪽 순
  14. 알파 테스트 오브젝트는 대체로 앞에서 뒤쪽 순
    • skybox.
  15. 알파 블렌드 오브젝트 (필요한 경우 앞에서 뒤쪽으로)
  16. 모바일에서 포스트 프로세싱은 부하가 높기 때문에 신중하게 사용합니다.
  17. 파티클 : 오버 드로우를 줄이고 가능한 한 간단한 쉐이더를 사용합니다.
  18. 메쉬의 더블 버퍼가 매 프레임 업데이트됩니다 :
void Update (){
  // flip between meshes
  bufferMesh = on ? meshA : meshB;
  on = !on;
  bufferMesh.vertices = vertices; // modification to mesh
  meshFilter.sharedMesh = bufferMesh;
}

쉐이더 최적화(Sharer optimizations)

필레이트에 의해 제한되어 있는지 판단하는 것은 쉽습니다 : 화면 해상도를 낮추면 게임이 빨라집니까? 만약 그렇다면, 필레이트에 의해 제한되어 있습니다.

다음의 방법으로 쉐이더의 복잡성을 줄일 수 있습니다 :

  • 알파 테스트 쉐이더를 피합니다. 대신 알파 블렌드 형식을 사용합니다.
  • 심플하고 최적화된 쉐이더 코드를 사용합니다 (Unity 출하 시의 Mobile 쉐이더와 마찬가지로).
  • 쉐이더에서 부하가 높은 math 함수의 사용을 피합니다 (pow, exp, log, cos, sin, tan 등). 대신 미리 계산된 룩업 텍스처를 사용하는 것을 고려하십시오.
  • 가능한 한 낮은 정밀도의 형식을(float, half, fixedin Cg) 사용하여 최고의 퍼포먼스를 얻습니다.

CPU로의 포커스

게임이 GPU의 픽셀 처리에 의해 제한되고 있는 경우가 많습니다. 결과적으로, 특히 멀티 코어 모바일 CPU에서 사용하지 않은 CPU 처리 능력이 남게 됩니다. 따라서 GPU 작업을 대신하여 CPU에 바꿔 붙이는 것이 효과적입니다 (Unity는 이것을 모두 자동으로 수행합니다) : 메쉬 스키닝, 작은 오브젝트의 배칭, 파티클 오브젝트의 업데이트 등.

이들은 맹목적으로 사용될 것이 아니라 신중하게 사용되어야 합니다. 드로우콜에 의해 제한되지 않은 경우, 배칭은 퍼포먼스에 나쁜 영향을 주며, 컬링의 효율성을 낮출 뿐만 아니라 빛에 의해 영향을 받는 오브젝트 수를 늘려버립니다.

Good practice

  • FindObjectsOfType(및 Unity의 프로퍼티 getter 전반)은 매우 느리므로, 분별있게 사용하십시오.
  • 이동하지 않는 오브젝트의 Static 프로퍼티를 사용하여 정적 배칭 같은 같은 내부 최적화를 허용하십시오.
  • CPU 사이클을 대량으로 소비하여 오클루전 컬링과 더 낳은 소트(Sorting)를 실시 (Early Z-cull을 활용하기 위해) 하십시오.

Physics

물리 계산은 무거운 CPU 처리를 포함합니다. 에디터 프로파일러를 이용하여 프로파일링 할 수 있습니다. 만약 CPU에서 물리 계산 시간이 오래 걸리는 경우 :

  • Time.fixedDeltaTime (Project settings -> Time에서)을 조정하여 가능한 한 크게합니다. 만약 게임이 느린 동작이라면 빠른 액션를 요구하는 게임보다 fixed update를 작게 하는 것이 좋습니다. 빠른 액션을 요구하는 게임은 계산이 더 자주 필요하고, 결과적으로 fixedDeltaTime 을 더 작은 값으로 하지 않으면 충돌이 제대로 작동하지 않을 수 있습니다.
  • Physics.solverIterationCount (Physics Manager).
  • 가능한 한 천(Cloth) 오브젝트를 적게 사용합니다.
  • Rigidbody는 필요한 경우에만 사용 합니다.
  • 기본 설정 메쉬 콜라이더에서 원시(primitive) 콜라이더를 사용합니다.
  • 정적 콜라이더(즉 Rigidbody없는 콜라이더)는 퍼포먼스 영향이 몹시 크니 절대로 움직이지 않을 것. 프로파일러에 Static Collider.Move_라고 표시되지만, 실제 작업은 Physics.Simulate_에 있습니다. 만약 필요하다면 RigidBody를 추가하여 _isKinematic_에 true를 설정합니다.
  • Windows에서 NVidia의 AgPerfMon 프로파일링 도구를 사용하여 필요한 경우, 보다 상세한 정보를 얻을 수 있습니다.

Android

GPU

이들은 인기있는 모바일 아키텍처입니다. 이것은 PC / 콘솔에서 둘 다 다른 공급 업체이며, 일반 GPU와 다른 GPU 아키텍처입니다.

  • ImgTec PowerVR SGX - 타일 기반, 지연 : 모든 것을 작은 타일로(16x16로) 렌더링 하고, 표시되는 픽셀만 쉐이드합니다.
  • NVIDIA Tegra - Classic: 모든 것을 렌더링
  • Qualcomm Adreno - 타일 : 전체를 타일 렌더링하고, 큰 타일로(256k로) 처리합니다.
  • ARM Mali Tiled : 전체를 타일로(16x16로) 처리하고 렌더링합니다.

다른 렌더링 방식을 검토하고, 그것에 맞춰 게임을 설계합니다. 소트에는 특별히 주목합니다. 개발 사이클의 초기 단계에서 지원하는 최저한의 로우 엔드 장치를 결정합니다. 게임을 디자인 할 때 프로파일러를 사용하여 테스트합니다.

플랫폼 특유의 텍스처 압축을 사용합니다.

더 읽을 거리

화면 해상도

Android 버전

iOS

GPU

PowerVR 아키텍처(타일 기반 지연)만 신경쓰면 된다.

  • ImgTec PowerVR SGX. 타일 ​​기반, 지연 : 전체를 타일로 렌더링하고, 표시되는 픽셀만 쉐이드합니다.

즉,:

  • 밉맵은 그다지 필요하지 않다.
  • 안티 앨리어싱 및 Aniso(이방성)는 충분히 싸고, iPad 3은 경우에 따라 필요 없습니다.

또한 단점으로 :

  • 만약 프레임마다 정점 데이터(정점 × 정점 쉐이더 후 필요한 저장소)가 드라이버에서 할당한 내부 버퍼를 초과하면, 씬은 “분할”될 필요가 있으며, 퍼포먼스가 소비됩니다. 드라이버가 나중에 더 큰 버퍼를 할당하거나 정점 수를 줄여야 할 지도 모릅니다. 이것은 iPad 2(iOS 4.3) 10만 정점의 매우 복잡한 쉐이더에서 명백 합니다.
  • 타일 기반 지연 렌더링(TBDR)은 더 많은 트랜지스터를 타일링 및 디퍼드 부분에 할당해야 하며, 개념적으로는 “raw performance”에 할당된 트랜지스터가 줄어듭니다. TBDR에서 GPU 타이밍을 얻는 것은 어렵고, 프로파일링이 어려워집니다.

더 읽을 거리

화면 해상도

iOS 버전

동적 오브젝트

에셋 번들

  • 에셋 번들은 장치에서 특정 한도 까지만 캐시 됩니다.
  • 에디터 API를 사용하여 생성 *로드에 WWW API를 사용 : WWW.LoadFromCacheOrDownload 또는 리소스로 AssetBundle.CreateFromMemory 및 AssetBundle.CreateFromFile을 사용한다
  • Unload using AssetBundle.Unload. There is an option to unload the bundle, but keep the loaded asset from it. Also can kill all the loaded assets even if they’re referenced in the scene
  • Resources.UnloadUnusedAssets unloads all assets no longer referenced in the scene. So remember to kill references to the assets you don’t need. Public and static variables are never garbage collected.
  • Resources.UnloadAsset unloads a specific asset from memory. It can be reloaded from disk if needed.

iOS에서 에셋 번들의 동시 다운로드 수에 제한이 있나요? (예를 들어, 동시에(또는 매 프레임) 10개의 에셋 번들을 안전하게 다운로드 할 수 있습니까?)

다운로드는 OS에서 제공하는 비동기 API에 의해 구현되어 있기 때문에, OS는 얼마나 많은 스레드를 다운로드를 위해 만들어야 할 지 결정합니다. 여러 개의 동시 다운로드를 시작할 때 장치가 지원할 수있는 총 대역폭 및 메모리 공간을 염두해 둘 필요가 있습니다. 각각의 동시 다운로드 대상은 임시 버퍼를 할당하기 때문에 메모리가 부족하지 않도록 주의해야 합니다.

Resources

  • Assets need to be recognized by Unity to be placed in a build.
  • Add .bytes file extension to any raw bytes you want Unity to recognize as a binary data.
  • Add .txt file extension to any text files you want Unity to recognize as a text asset
  • Resources are converted to a platform format at a build time.
  • Resources.Load()

Silly issues checklist

  • Textures without proper compression
  • Different solutions for different cases, but be sure to compress textures unless you’re sure you should not.
  • ETC/RGBA16 - default for android but can tweak depending on the GPU vendor. Best approach is to use ETC where possible. Alpha textures can use two ETC files with one channel being for alpha
  • PVRTC - default for iOS, good for most cases
  • Textures having Get/Set pixels enabled - doubles the footprint, uncheck unless Get/Set is needed
  • Textures loaded from JPEG/PNGs on the runtime will be uncompressed
  • Big mp3 files marked as decompress on load
  • Additive scene loading
  • Unused Assets that remain uncleaned in memory.
  • If it randomly crashes, try on a devkit or a device with 2 GB memory (like Ipad 3).

Sometimes there’s nothing in the console, just a random crash

  • Fast script call and stripping may lead to random crashes on iOS. Try without them.
프로파일링
Practical Guide to Optimization for Mobiles