유니티는 C#으로 개발하기 때문에 느리다?
-> C#은 개발의 효율성을 위해 유저 코드가 C#으로 이루어 지지만, Unity 엔진은 C++로 구성되어 있어 실제로는 빠르게 개발할 수 있다.
이러한 구조를 알기 위해선 C#과 C++의 차이점을 알아야 한다.
- 동적할당
C++은 new를 선언하게 되면 항상 delete를 통해 동적할당을 끝맺어야 한다.
그렇지 않으면 메모리는 계속적으로 new에 대한 값을 갖게 되며 결과적으로 메모리에 대한 과부하가 일어나게 되기 때문이다.
하지만 C#은 GC (Garbage Collection)이라는 기능이 알아서 처리해주기 때문에 좀 더 편하게 작업을 진행 할 수 있다.
--> 이러한 점으로 미루어 보아, C#은 동적할당 해제 필요성이 없기 때문에 코드 작성에 있어 C++과 비교하여 좀 더 빠르게 스크립팅을 할 수 있는 장점이 있다.
하지만, C++은 유저가 메모리를 직접 해제하여 불필요한 메모리 누수가 없으므로 C#에 비해 컴퓨터 친화적인 스크립팅을 할 수 있다.
C#은 어떻게 Android나 IOS와 같은 환경에 최적화 되어 작동하는가?
--> 결론부터 이야기하면 C#은 IL이라는 중간언어를 통해 mono라는 최적화 프레임워크를 통해 안드로이드 및 IOS에 구동이 되고 있다. 이것이 흔히 우리가 Unity에서 보는 Scripting Backend의 하나인 Mono이다.
IL(CIL)이란?
공통 중간 언어(Common Intermediate Language, CIL)는 공통 언어 기반과 닷넷 프레임워크에서 인간이 이해할 수 있는 가장 낮은 수준의 프로그래밍 언어이다. 닷넷 프레임워크를 대상으로 하는 언어들은 바이트코드로 변환되는 CIL로 컴파일된다. CIL은 객체 지향 어셈블리어이며 완전한 스택 기반이다. 가상 머신을 통해 실행된다.
닷넷 프로그래밍 언어를 컴파일하는 동안, 소스 코드는 플랫폼, 프로세서 특유의 목적 코드가 아닌, 공통 중간 언어 코드로 변환된다. 공통 중간 언어는 닷넷 프레임워크를 지원하는 환경에서 실행할 수 있는, CPU와 플랫폼 독립 명령어 세트이다. 공통 중간 코드는 실행되는 동안에 안전 여부를 확인함으로써 완전한 이진 파일보다 더 나은 보안과 신뢰성을 제공한다.
이러한 Mono 형식은 우리가 흔히 Unity에서 테스팅할 때 사용되는 재생(에디터 모드)이 이러한 원리로 이루어지고 있다.
IL2CPP는 Mono와 무엇이 다른가?
-> 위의 그림에서 볼 수 있듯, C#에서 IL로 변환하는 과정은 Mono를 통해 이루어지기 때문에 다르지 않지만 IL에서 C++로 Unity에서 변환을 시켜주어 효율성을 높여주는 과정이다.
C++로 바꿔주는 과정이 왜 효율성을 높이는가?
C++은 IOS에서 제공하는 ObjectC언어와 호환이 되어 사용이 가능하며, Android는 NDK(Native Development Kit)를 통해 네이티브 언어인 C, C++과 호환이 되어 사용이 가능하다.
이러한 과정은 C++로 내부가 이루어져있는 Unity가 좀 더 빠르고 최적화된 빌드 과정을 이루게 도울 수 있다. Mono 프레임 워크를 통한 빌드는 JIT(Just In Time)으로 그때 그때 변환을 통해 이루어졌다면, IL2CPP 방식은 AOT 컴파일을 통해 이루어지므로 높은 성능의 빌드를 할 수 있게 된것이다.
AOT 컴파일이란 무엇인가?
AOT 컴파일(ahead-of-time compile)은 목표 시스템의 기계어와 무관하게 중간 언어 형태로 배포된 후 목표 시스템에서 인터프리터나 JIT 컴파일 등 기계어 번역을 통해 실행되는 중간 언어를 미리 목표 시스템에 맞는 기계어로 번역하는 방식을 지칭한다. 이런 중간 언어로는 자바 바이트코드, 공통 중간 언어(Common Intermediate Language), IBM System/38 혹은 IBM System i의 기술 독립적 머신 인터페이스(Technology Independent Machine Interface)가 있으며 학계에서도 마이클 프란즈(Michael Franz)[1]가 제안해 오베론 시스템의 일부 구현에서 사용된 슬림 바이너리(Slim Binaries)와 같은 제안이 있었다.
일반적으로 중간 언어를 사용하는 시스템은 실행 시간에 JIT 컴파일과 같은 기법을 통해 실행 시에만 얻을 수 있는 프로그램 분석 정보를 사용하여 높은 성능을 달성할 수 있다. 특히 객체 지향 언어나 스크립트 언어 같이 동적인 언어인 경우 효과적이다. 하지만 실행 시 프로그램 분석과 컴파일을 함께 수행하는데 추가 메모리 및 CPU 사이클이 필요한 단점이 있다. 따라서 AOT 컴파일은 이에 대한 보완책으로 사용되고 있다.
응용 범위
- 메모리 및 CPU 제약이 있는 경우: 인터프리터는 너무 느리고 JIT 컴파일은 너무 부담이 큰 경우로 임베디드 시스템인 경우가 많다. 단 이 경우 목표 시스템에 내장 되는 프로그램에 한해서 AOT 컴파일을 하고 내려받는 프로그램은 인터프리터나 JIT 컴파일로 실행하는 경우가 보통이다.
- 프로그램 특성 상 빠른 시작 시간과 일관된 성능이 중요한 경우: 데스크톱 환경에서 그래픽 사용자 인터페이스 위주의 프로그램인 경우가 이에 해당 한다.
- 전통적인 컴파일러 최적화가 효과적인 경우: 계산이 많은 프로그램처럼 일반 컴파일을 통한 최적화가 효과적인 경우에 사용할 수 있다. AOT 컴파일은 소스 코드 대신 중간 언어를 받아 들인다는 점을 빼면 일반적인 정적 컴파일과 동일하기 때문에 실행 시간에 비해 충분한 프로그램 분석을 통해 최적화를 보여준다.
https://ko.wikipedia.org/wiki/AOT_%EC%BB%B4%ED%8C%8C%EC%9D%BC
AOT 컴파일 - 위키백과, 우리 모두의 백과사전
AOT 컴파일(ahead-of-time compile)은 목표 시스템의 기계어와 무관하게 중간 언어 형태로 배포된 후 목표 시스템에서 인터프리터나 JIT 컴파일 등 기계어 번역을 통해 실행되는 중간 언어를 미리 목표
ko.wikipedia.org
'정리 > UNITY' 카테고리의 다른 글
Unity 성능 향상을 위한 권장사항 (Microsoft) (0) | 2022.04.28 |
---|---|
Menu_UI 기능 구현 (0) | 2022.04.25 |
효율적 UI_Component 바인딩 (0) | 2022.03.08 |
Unity Shader (셰이더) (0) | 2022.03.08 |
Line Rederer (라인 렌더러) (0) | 2022.02.09 |