Unity Editor on Linux and the high CPU usage problem

Linux is not for gaming

Die-hard Linux fans have often had to revel in (or struggle with) the idea that their OS of choice isn't the number one target for game development. Partly due to the nature of FOSS and how it is supported, and partly due to the perceived uses of Linux as being for nerds and servers.

But this is changing, slowly. if a Linux user is willing to put aside their distaste of proprietary software and take a pragmatic approach, there are tools available to allow people to no dirty their hands with other operating systems. Indeed, Unreal Engine 4 is completely Open Source and available on GitHub.

Unity was arguably the first game engine to reach the mainstream, with its slick editor, lively asset store, and large community. Users of the software have been asking for a Linux build of the editor for years. The Windows and OSX versions could build Linux games, but the editor could only be run in Wine on Linux, with varying levels of success. Last year however, the Unity developers released a (very) beta build of the editor, and there was much rejoicing. People understood that it was very much a side project, probably full of bugs, and perhaps not ready for the big time, but it was a welcome start.

The bug that wouldn't die

But reports starting appearing on the forums that for some people the editor was running a CPU core at 100% while idle, and only running the game in the editor calmed the CPU down. Several updates to the editor have been released and still there are reports of high CPU usage. Not everybody was suffering the problem, but a significant number, including me, had their CPU fans running constantly which made it less than fun. The Unity developers seem silent on the matter, possibly because not many resources are being thrown at it.

Various solutions have been posted by users, mostly scripts that limit the CPU for that particular process, but that's a bit drastic. So I got to thinking, what is it about running even an empty scene that reduces the CPU usage? I also noticed swinging the camera around in the editor had the same effect, and when I stopped moving the camera the CPU pegged again. But it wasn't until I looked in the About dialog box to find which version I was running, that I realised what the problem might be.

A fix less hacky

You see, the About box has a scrolling list of the many contributors to Unity, and when it gets to the bottom of the list it loops around, and having this box open reduced the CPU usage to normal. The editor was doing something. Not much, but not idling either. And as it is a modeless window, it can be minimised and it still reduces CPU usage. Granted, if you tab away from and then back to the main editor window it restores the About box, but it's better than nothing.

Why?

This is pure speculation on my part, but what I think is happening is that somewhere inside the editor there is an event loop, a function that waits for events such as mouse movements, keyboard input, or redraw requests. If it gets an event, it broadcasts that to any part of the application that is listening so it can be handled. Because of the arbitrary nature of these events, event loops are usually single-threaded to avoid reentrancy problems and so on. Much of the time, there are no events coming in, and so the event loop should sleep until it is called again to check for incoming events. This sleep function instructs the OS to do other stuff with the time it was allocated. But if the sleep function isn't called, the event loop will spin as fast as it can taking up all the time allocated to it, and I think it is this that is happening to the Unity editor. Somewhere in the code either the sleep function is wrapped in a condition that is false when there are no events, or the sleep function itself is failing for some reason.  If I am on the right lines, my money is on the former.

A slightly better workaround

The Unity editor is extensible with custom controls and plugins, and people have come up with some fantastic tools. But what if someone created a simple widget that redrew itself every frame? Regardless of user input, and drawing nothing more than the window decorations, it should generate enough events to keep the event loop quiet. So that's what I did:

using UnityEngine;
using UnityEditor;

[ExecuteInEditMode]
public class Idler : EditorWindow {
[MenuItem("Window/Idler")]
public static void ShowWindow() {
GetWindow(typeof(Idler));
}

void Update() {
Repaint();
}
}

Put this script somewhere in your project, activate it from the Window menu, and dock it somewhere out of the way. It does have to be visible, so you can't put it on a tab bar with other windows. It also has a minimum size, so it won't disappear completely. I tried using the OnInspectorUpdate() function which is called less often than Update(), but that didn't make much difference because there is still plenty of time where the event loop is idle.

The preferred fix

Of course, the best way of solving the problem is for the Unity developers to actually fix the code. I appreciate that support for a Linux build is practically non-existent because it's really quite a niche market and they don't want to, or aren't able to, provide the resources necessary. But just having someone spend an afternoon looking for the bug isn't too much to ask, is it?