Recently we talked about Unity and WebGL. In that post we briefly spoke about how scripting works in WebGL, using new technology called “IL2CPP”. However, IL2CPP represents a lot more than just a scripting solution for WebGL; it’s our own high performance .NET Runtime, to be rolled out on more platforms.
But before we delve into the future, let’s talk about the present.
Scripting in Unity today
We leverage Mono (and WinRT on Windows Store Apps and Windows Phone) to bring the ease of use of C#, access to 3rd party libraries, and near native performance to Unity. However, there are some challenges:
- C# runtime performance still lags behind C/C++
- Latest and greatest .NET language and runtime features are not supported in Unity’s current version of Mono.
- With around 23 platforms and architecture permutations, a large amount of effort is required for porting, maintaining, and offering feature and quality parity.
- Garbage collection can cause pauses while running
These issues have remained in the front of our minds over the past few years as we sought to address them. Concurrently, investigations into supporting scripting for WebGL were occurring. As each progressed forward, these two paths converged into a single approach.
With the problem scope clear, experimentation on different ways to solve this were tried. Some of them were promising; others were not. But ultimately we found an innovative solution and it proved to be the right way forward.
That way forward is IL2CPP.
IL2CPP: the quick and dirty intro
These two parts represent our own implementation of the Common Language Infrastructure, similar to .NET or Mono. It is compatible with the current scripting implementation in Unity.
Fundamentally, it differs from the current implementation in that the IL2CPP compiler converts assemblies into C++ source code. It then leverages the standard platform C++ compilers to produce native binaries.
At runtime this code is executed with additional services (like a GC, metadata, platform specific resources) that are provided by the IL2CPP VM.
The benefits of IL2CPP.
Let’s talk about each one of the previously mentioned issues and how IL2CPP addresses each of them.
IL2CPP seeks to provide the ease of use and productivity of C# with the performance of C++.
It allows the current, productive scripting workflow to remain the same while giving an immediate performance boost. We’ve seen 2x-3x performance improvements in some of our script-heavy benchmarks. This performance boost is due to a few reasons.
- C++ compilers and linkers provide a vast array of advanced optimisations previously unavailable.
- Static analysis is performed on your code for optimisation of both size and speed.
- Unity-focused optimisations to the scripting runtime.
While IL2CPP is definitely still a work in progress, these early performance gains are indicative of great things to come.
A very frequent request we get is to provide an upgraded runtime. While .NET has advanced over the past years, Unity currently supports .NET 2.0/3.5 era functionality for both the C# compiler and the class libraries. Many users have requested access to newer features, both for their code as well as 3rd party libraries.
To complement IL2CPP, as it matures, we will also be upgrading to recent versions of the Mono C# compiler, base class libraries, and runtime for use in the editor (The editor will not switch to IL2CPP, for fast iteration during development). These two things combined will bring a modern version of .NET to Unity.
It’s also important to note that we are collaborating with Microsoft to bring current and future .NET functionality to Unity, ensuring compatibility and quality.
Portability and Maintenance
While this area may sound like an internal issue for Unity to deal with, it also affects you. The Mono virtual machine has extensive amounts of platform and architecture specific code. When we bring Unity to a new platform, a large amount of our effort goes into porting and maintaining the Mono VM for that platform. Features (and bugs) may exist on some platforms but not others. This affects the value which Unity strives to provide to you; easy deployment of the same content to different platforms.
IL2CPP addresses these issues in a number of ways:
- All code generation is done to C++ rather than architecture specific machine code. The cost of porting and maintenance of architecture specific code generation is now more amortised.
- Feature development and bug fixing proceed much faster. For us, days of mucking in architecture specific files are replaced by minutes of changing C++. Features and bug fixes are immediately available for all platforms. In it’s current state, IL2CPP support is being ported to new platforms in short amount of time.
Additionally, platform or architecture specific compilers can be expected to optimise much better than a singular code generator. This allows us to reuse all the effort that has gone into the C++ compilers, rather than reinventing it ourselves.
IL2CPP is not tied to any one specific garbage collector, instead interacting with a pluggable API. In its current iteration IL2CPP uses an upgraded version of libgc, even as we look at multiple options. Aside from just the GC itself, we are investigating reducing GC pressure by analysis done in the IL2CPP compiler.
While we don’t have a lot more to share at the moment, research is ongoing. We know this is important to many of you, we’ll continue working on it and keep you informed in future blog posts. Unrelated to IL2CPP, but worth mentioning in the context of garbage collection, Unity 5 will see more and more allocation free APIs.
What IL2CPP is not
IL2CPP is not recreating the whole .NET or Mono toolchain. We will continue to use the Mono C# compiler (and perhaps later, Roslyn). We will continue to use the Mono class libraries. All currently supported features and 3rd party libraries which work with Mono AOT should continue to work with IL2CPP. We are only seeking to provide a replacement for the Mono VM and AOT compiler, and will keep on leveraging the wonderful Mono Project.
When can I try IL2CPP?
By now we hope you are just as excited as we are to use IL2CPP and wondering when you can get your hands on it! An early version of IL2CPP will be available as part of WebGL publishing in Unity 5.
Beyond WebGL, we are continuing development of IL2CPP for other platforms. In fact, we already have working implementations on a number of our supported platforms. We expect to be rolling out at least one additional platform later this year. Our current plan is to have iOS be the next platform shipping with IL2CPP support.
The planned upgrades of our Mono toolchain will follow after IL2CPP is available on more platforms and has matured.
One platform that will never be supported by IL2CPP is the WebPlayer; this is due to security implications. And as noted earlier, the editor will remain to be using Mono.
Additionally, you can see the IL2CPP runtime in action today. As mentioned, the two WebGL demos we posted are IL2CPP-powered.
We are still hard at work on IL2CPP: implementing new features, optimising code generation, fixing bugs, and supporting more platforms. We’ll keep posting more in-depth blogs as we make progress and talk about it with you on the forums.
The Scripting Team.