티스토리 뷰
프로파일러에서 graphics.blit/device.present 항목으로 대기하는 부분은 gpu boundary 즉, gpu job이 끝날때까지 cpu가 대기하고 있다고 보면 된다.
프로파일러에서 calls가 높고 ms가 높다면, cpu에서의 draw call이 높다고 볼 수 있다.
Gpu 프로파일링
Fillrate = 화면 픽셀수 x 프래그먼트 쉐이더 복잡도 x 오버드로우
gpu의 경우 유니티 프로파일러로는 측정이 불가함.
최근 디바이스의 경우 해상도가 hd 이상으로 올라가는 경향이므로 dpi를 조절하는게 의미가 있음.
프로파일링하다가 dpi를 줄였을때 의미있는 결과가 나오면 gpu 병목인지를 가늠해볼 수 있다.
오버드로우 병목의 경우는 보통 파티클이 많아져서 겹치는 경우가 잦다.
과도한 post process의 경우 fragment shader의 복잡성에 영향을 줌.
해서 ui의 해상도는 그대로 두고, rendering하는 부분의 scale을 줄이면 성능에 도움을 줌.
urp의 경우 universal render pipeline asset에 quality에서 render scale을 줄일 수 있음.
Texture Compression
png, jpg로 해서 용량이 적다고해서 on texture memory가 적지 않음.
압축 format 으로 설정. 원본포멧은 아무상관없음.
PVRTC > iOS, 알고리즘상 blur가 생김.
ETC1,ETC2 > 밝기 베이스로 대비 압축 방식
POT (power of 2)사이즈로 만들어야 압축 알고리즘시 비효율이 생김
ASTC (가변형 블럭설정) 2x2~12x12 낮을수록 정밀도 높음. opengl 3.1이상은 다 지원함.
Frame Debugger
순간 프레임의 draw과정을 전부 볼수 있으며 batching이 깨지는 이유에 대해서도 알 수 있음.
쉐이더에서 의도적으로 batching을 끌 수 있음.
tags { "RenderType" = "Opaque", "DisableBatching" = "True" }
sprite renderer의 경우 additional settings에서 별도의 sorting layer를 지정해서 bating을 할 수 있도록 함.
오브젝트의 layer 지정을 해서 batching을 할 수 있도록 잘 묶어야함.
Memory Profiler
package manager에서 따로 추가해야함.
sprite atlas로 ui를 묶어보는것이 좋음. sprite tag와 다름, packing tag는 사용하지 말자. (sprite packer와 비슷)
ETC2는 ES3.0부터 지원 하위버전에서 사용하면 압축이 풀려서 메모리에 적재되게됨.
editor코드로 일괄 적용예
using UnityEditor;
public class ResourceModifierTest : AssetPostprocessor {
void OnPreprocessTexture() {
var importer = (assetImporter as TextureImporter);
if (importer.textureType == TextureImporterType.Sprite) {
importer.SetPlatformTextureSettings("Android", 1024, TextureImporterFormat.AutomaticCompressed);
importer.SetPlatformTextureSettings("iPhone", 1024, TextureImporterFormat.AutomaticCompressed);
importer.SetAllowsAlphaSplitting(true);
importer.mipmapEnabled = false;
}
}
}
audio의 경우 load type을 지정할 수 있음.
Decompress On Load의 경우 효과음만 사용 (bgm에는 치명적)
iOS에서는 mp3사용 권장 (ogg 네이티브 지원하지 않음)
유니티는 중복파일 체크를 하지 않으므로 주의
using UnityEditor;
public class ResourceModifierTest : AssetPostprocessor {
void OnPreprocessModel() {
var importer = (assetImporter as ModelImporter);
importer.isReadable = false;
importer.optimizeMesh = true;
if (assetPath.Contains("@")) {
// 애니메이션의 경우는 마테리얼을 임포트 하지 않아서 false.
importer.optimizeMesh = false;
}
}
}
코드작성팁
유니티플레이어 루프의 이해필요. (awake, onenable, update, fixedupdate의 타이밍)
FPS는 30이지만 fixedupdate는 50으로 설정한경우 오버헤드 발생여지가 있으므로 fixed timestep도 적정조정이 필요하다.
- 적절한 targetFrameRate설정
- 장르별, 상황별
- Adaptive Performance
- 비동기 로딩사용
- Assetbundle.LoadFromFileAsync()
- Assetbundle.LoadAssetAsync()
- 사용하지 않는 Monobehaviour 메소드 제거
- Start(), Update(), FixedUpdate() 등등
- 비싼 api의 빈번한 호출 주의
- GameObject.Find(), GameObject.GetComponent(),,
- 스트링 오퍼레이션 주의 (use Stirngbuilder)
- Debug.Log주의
- [Conditional("ENABLE_LOGS")]
- 따로 wrapping해서 위 tag를 걸어서 빌드에 포함되지 않도록 필요.
- allocating api 주의
- Component.GetComponets(), Animator.parameters..
- 정적 데이터 파싱 주의
- xml/json 대신 scriptable object를 사용하기.
xml이나 json을 읽을때 아무래도 alloc이 생김.
'Unity > 최적화' 카테고리의 다른 글
[Youtube] 유나이트 서울 2020 - Unity 엔지니어를 위한 Profiler 노하우 (0) | 2021.02.26 |
---|---|
[Youtube] 유나이트 서울 2020 - 최대 성능을 위한 최적화 팁 (0) | 2021.02.26 |
[Youtube] 유나이트 서울 2020 - Adaptive Performance를 활용한 모바일 단말의 지속성능 최적화 Track2-5 (0) | 2021.02.25 |
[UnityBlog] 어댑티브 퍼포먼스 (Adaptive Performance) (0) | 2021.02.24 |
Unite Now: 버스트 컴파일러를 사용한 Android 모바일 최적화 (0) | 2021.02.24 |
- Total
- Today
- Yesterday