IL2CPP 1장
IL2CPP & Burst
최적화거나 프로파일링을 이해하기 위한 지식이다.
많은 사람들이 하는 오해? -> 유니티는 C#이라서 느리다??
유니티 내부는 Cpp로 되어있다. 따라서 느리지 않다.
겉은 C#이고, 내부 엔진은 Cpp로 되어있다.
IL2CPP 라는 요즘은 이야기를 많이 들을것이다.
도입되며 유저 코드부분도 Cpp로 돌릴 수가 있다.
엔진 내부도, 유저 코드도 Cpp로 돌릴 수가 있어서 전반적인 성능이 높아지는것이다.
IL2CPP란
C# / C++ / C 가 있다.
쌩 C의 경우에는 거의 쓰이지 않는다. Cpp아니면 C#을 이용하는데
Cpp에서 객체지향이 적용되기 시작하였다.
Cpp는 메모리 관리를 직접 해주어야 한다. new / delete
쓰레드도 직접 고민을 해줘야 하는 부분이 많다.
-> C#을 마이크로소프트에서 만들었는데
MS에서 .net프레임워크 기반으로 돌아가는 언어를 개발하였다.
C#은 메모리관리를 직접 해주기때문에 생산성이 좋다.
new로 할당을 해주면 GC가 알아서 메모리 해제를 해준다.
Cpp에 비해 굉장히 쉬워 졌다.
다만, 그만큼 매니지드메모리를 사용하기 때문에, Cpp에 비해 성능저하가 있다.
생산적인 부분이 훨씬 크기때문에 프론트에서 많이 개발을 한다.
C#으로 개발하는데 최종적으로 안드로이드, IOS에서도 사용을 하는데 이는
Mono라는 프레임워크를 사용하기 때문이다.
Mono는 닷넷 프레임워크를 대응하기 위해 만든것이다.
Android, Ios, 플스, 앱박스에서도 돌아가고 멀티플랫폼을 대응하여 C#을 돌릴수있는 프레임워크이다.
원래 오픈소스로 시작했는데, MS에서 가져가서 자마린 프로젝트로 발전시키며 모노도 발전을 한다.
윈도우뿐만이 아니라 맥북까지도
C#은 IL (중간언어_닷넷 어셈블리라고 표현할수 있다.)로 변환 후 이 IL을 MONO상에서 돌린다.
C# -> IL 로 변환되고, Mono로 빌드를 하게되면 IL이 탑재가된다. 이 모노가 런타임상에서 파싱을하며 여러가지 플랫폼 위에서 돌게 되는것이다.
이 방식이 JIT 컴파일 방식이라고 한다. Just In Time -> 그때 그때 필요할때 컴파일 한다는 개념이다.
IL자체가 기계어가 아니다. 중간형태의 언어이다.(사람이 읽을 수도 있다.)
인터프리터와는 좀 다른 개념이다. -> 유저 코드자체를 실시간으로 파싱하며 돌리는 거라 굉장히 느린 방식
JIT은 한번 변환된 어셈블리를 갖고, 타겟 디바이스에 맞게 컴파일하기때문에 빠르다. 다만 미리 바이너리화 해놓은것보단 느리다.
IL2CPP는 IL을 Cpp로 만들어 주는것이다.
C#에서 IL로 바꾼것이 기존 프로세스라면 (MONO 컴파일러)
유니티에서는 IL을 CPP로 만들어주는 중간단계를 추가해준것이다.
CPP로 만들면 안드로이드, Object C, NDK를 통해 안드로이드의 심장에 Cpp로 꽂을수있음
즉, 속도도 빠르고 굉장히 다양한 플랫폼에서 돌릴 수가 있게 된다.
결론적으로
C# -> IL -> Mono => JIT방식 (미리 컴파일이 아닌, 그때그때 컴파일)
C# -> IL -> C++ => AOT방식 (미리 컴파일해놓은 방식이 된다.)
개발할때는 JIT방식으로 에디터에서는 빠른 생산성을 갖고가고, 빌드할때는 IL2CPP로 성능을 챙기는 방식을 선택하고 있다.
우리가 작성한 C#은 코드편집기에서 ILViewer를 통해 IL로 변환된 내용을 볼 수가 있다.
또한 빌드를 해보면
IL2CPP 폴더내부에서 cpp로 작성된 파일들을 볼 수가 있는데
내부가 cpp로 작성이 되어있다.
만약 내가 어떤 클래스의 어떤 함수를 알고 싶다면
클래스 이름_어떤 함수 _ 유니크한 숫자들 형식으로 이루어진 함수를 찾으면 된다.
관련 인자들도 함께 있다.
이러한 방식을 알고있어야. 디버깅하거나 프로파일링할때 도움이 된다고 한다.
파일 내부를 들여다보면 주석 또한 함께 달려있다.
https://www.youtube.com/watch?v=-9X965jXrn8