For all of the nice things about C#, writing code with it also comes with a lot of downsides. We spend so much time working around the garbage collector, working around IL2CPP, and worrying about what’ll happen if we use a foreach loop. Today’s article starts a series that explores what would happen if we escaped .NET and wrote our code as a C++ plugin instead of using C#.
Using the Unity API from Other Threads
The Unity API can mostly only be used from the main thread. This is used as an excuse by Unity developers to write all their code on the main thread. This makes their code run 2-6x slower. So what can we do about it? Today’s article presents a simple way to use the Unity API from other threads. Read on to learn how to unlock all that extra CPU power!
Getting the Size of a Struct at Compile Time
I continue to learn a lot by reading the C++ code that IL2CPP outputs. Like reading decompiled code, it gives some insight into what what Unity’s build process is doing with the C# we give it. This week I learned that sizeof(MyStruct) isn’t a compile-time constant like it is in C++. Because of that, IL2CPP generates some less-than-ideal C++ code every time you use it. Today’s article shows the process I went through to work around that issue and ends up with some code you can drop into your project to avoid the problem.
Three Surprises I Encountered While Reading IL2CPP Output
We code in C#, but that’s just a starting point. Our C# code is compiled to DLLs and then converted into C++ where it’s compiled again to machine code. The good news is that this isn’t a black box! I’ve recently been reading through the C++ code that IL2CPP outputs and learning quite a lot. Today’s article is about some of the surprises that I encountered and how you can change your C# code to avoid some nasty pitfalls.
Making Structs More Useful with Object Handles
Structs can be a great way to keep the garbage collector off your back and to use the CPU’s data cache more effectively. Not everything can be a struct though. At a minimum, you’ll need to use some Unity and .NET classes like MonoBehaviour and string. If your struct has any of these as fields, you can no longer use sizeof(MyStruct). That really limits its usefulness, so a workaround is needed. Enter object handles: a simple way to represent any object as a plain old int which won’t break sizeof. Read on to see how these work and some code you can easily drop into your project to start using them right away!
The Easy Power of Code Generation
C# generics are weak. The where clause allows you to know a little about the generic (“T“) types you’re given, but that’s just scratching the surface of what you can do with code generation. Today’s article will show you how easy it is to add a little code generation to a project and the power that brings.
Do Even More At Once
Threads allow us do more than one thing at a time using the CPU’s cores, but it turns out we can do more than one thing at a time using just a single core! Today’s article shows you how you can do this and the huge speed boost it can give you!
The Other CPU Cache
We’ve seen how using the CPU’s cache can lead to a 13x speedup, but that’s only utilizing one of the CPU’s cache types. Today’s article shows you how to go further by utilizing a whole other type of CPU caching!
How to Use the Whole CPU
Last week’s article showed how to effectively use the CPU’s caches to boost performance by an order of magnitude. Today’s article goes even further to show you how to use even more of the CPU’s capabilities!
How to Write Faster Code Than 90% of Programmers
Most programmers write code for an abstract computer. The thing is- code runs on a real computer that works in a specific way. Even if your game is going to run on a wide range of devices, knowing some of the common features can speed up your code 10x or more. Today’s article shows you how!