How to improve gaming performance on your Linux machine

How to improve gaming performance on your Linux machine


You’ll need this:

  • Nvidia linux driver – Head to www.nvidia.com and download the latest driver (for info on AMD on Ubuntu see this page on BinaryDriverHowto)
  • Custom kernel – We used Zen kernel 3.8.8-zen which can be found at gitbut.

Now that Valve’s digital distribution platform is here for Linux along with a collection of native Linux titles the penguin operating system is garnering an increasingly higher profile as a serious gaming platform.

Steam Linux catalogue
The Linux catalogue of games is steadily growing.

As with Windows there are some tips and tweaks you can use to improve the performance of Linux as a gaming system but with a difference. The truth is that under Windows there’s little you can actually do to improve performance: you don’t have access to the code for the game binary the OS or the drivers. Most Windows tweaks revolve around disabling unnecessary services or programs in an effort to free up memory or CPU time and any difference if there is any is often negligible. Mostly the best you can do for a Windows system is to make sure you have the latest drivers installed. Or upgrade your hardware.

The same isn’t true for Linux. While the games will still have precompiled binaries the source code to Linux itself and especially the kernel is freely available. We’re undoubtedly going to see a rise in stripped-down gaming-oriented distributions (including Valve’s own version for its Steam Box we expect) although you can do some of your own tweaks to improve performance on your own system even for a desktop-oriented distribution like Ubuntu. With impressive results too as we’ll get into later.

So here’s our guide to optimising Linux for games.

Starting with drivers

Naturally while open-source drivers exist for both Nvidia and AMD cards and these work perfectly for the desktop better performance can be obtained by using the latest official binary drivers.

Ubuntu makes it easy for you to switch to these using the ‘Additional Drivers’ option in the ‘Software Sources’ dialogue – simply type software in the Unity bar to find and launch ‘Software Sources’ click on the ‘Additional Drivers’ tab and select which driver you want to use. You may get a selection that includes the latest untested driver (not necessarily beta simply not tested stable for Ubuntu’s repositories) or the latest tested version.

Of course this is the easy way. You can also install the very latest driver direct from the manufacturer which can often be quite useful as the Ubuntu repositories can often be a number of versions behind.

As our test system uses an Nvidia card and the process is a little more complicated than for AMD we’ll cover how to do this for Nvidia here. For a great guide on installing the latest drivers from AMD on Ubuntu see the community how-to at the Binary Driver Howto page.

Step 1

If you’re already using one of the Nvidia drivers from Ubuntu’s repositories first disable this driver by going to the ‘Additional Drivers’ tab in ‘Software Sources’.

Step 2

Head to www.nvidia.com and download the latest Nvidia Linux driver. Just as with Windows you can install the latest WHQL equivalent or the very latest beta. You’ll be asked to download a file ending in ‘.run’.

Step 3

Reboot and from the Grub menu choose the ‘Safe Mode’ version of your current kernel. You may need to click on ‘Advanced options’ first.

Step 4

From the ‘Safe Mode’ screen select to free up disk space or check your disk; either will remount your file system in read/write mode (it’s good to check every now and then!).

Step 5

Choose the ‘Root’ option to drop to a command prompt with root privileges and then change to the directory where you saved the Nvidia driver file.

Step 6

Run chmod a+x to make it executable followed by launching it; for example ./NVIDIA-Linux-x86_64-310.44.run . Select ‘Yes’ to all prompts during install.

Step 7

Finally the Nvidia driver won’t load while the open-source Nouveau driver is present but rather than uninstalling it simply prevent it from loading by running nano /etc/modprobe.d/blacklist.conf and adding blacklist nouveau to the end of the file. Press Ctrl+X to save.

Step 8

Run the command reboot to reboot with the driver installed.

Note that if you ever want to uninstall the driver and revert to Nouveau or an Ubuntu repository driver simply repeat the process above but when running the Nvidia installer append the switch --uninstall and then delete Nouveau from the ‘blacklist.conf’ file.

Finally if you plan to also compile your own kernel which we’ll cover next wait until you’ve installed the new kernel before installing the latest driver otherwise you’ll have to do it again afterwards!

 

Compiling a custom kernel

It’s long been known that running an optimised kernel can improve performance and like Windows which needs to support the lowest common denominator most Linux distributions use generic kernels configured to support and run on the widest range of hardware. But unlike Windows you can change this.

Compiling your own kernel is a fun and great learning experience if you haven’t done it before. You have a number of options available: you can use vanilla kernel source (upon which all distribution kernels are based) use Ubuntu’s patched kernel source or go hardcore and grab a performance patched kernel such as the Zen kernel.

Of course the real question is what difference can a custom kernel make especially when a game is still a precompiled binary. As it happens more than you might think – see our benchmarks results on the table below.

Since the process of compiling a vanilla kernel or a patched kernel is the same and we want to test whether using an optimised kernel makes a difference to games we’ll demonstrate using the build of the Zen kernel (3.8.8-zen at the time of writing).

Step 1

First head to Steven Barrett’s Github respository and click on the ‘Zip’ button to download a ZIP archive.

Step 2

Open a terminal run sudo -s and grab a drink. There’s a bit of work to be done.

Step 3

Install the necessary dependencies for compiling a kernel with apt-get install kernel-package libncurses5-dev.

Step 4

Next run cd /usr/src and then decompress the kernel ZIP file with unzip /home/[username]/Downloads/zen-kernel-3.8-master.zip (where [username] is your username if you saved it in your ‘Downloads’ directory).

Step 5

Set up a symlink for Linux for the kernel as the default source with ln -s zen-kernel-3.8-master linux .

Step 6

Change to the source directory cd linux .

Step 7

Run make menuconfig.

 

Next it’s time to configure the kernel. Use the cursor keys to navigate spacebar to select and Esc to move back a menu. There are hundreds of options in the kernel but we only need to toggle a few.

Step 8

Under ‘General Setup’ select ‘Automatically use SCHED_ISO policy for X’.

Step 9

Under ‘Processor type and features’ select your CPU type under ‘Processor Family’.

Step 10

Scroll down and make sure ‘Preemption Model’ is set to ‘Voluntary Kernel Preemption’.

Step 11

Scroll further down to ‘Timer Frequency’ and set this to 1000Hz.

Step 12

Press Esc until you’re asked to quit and save your configuration.

 

Most of the other options for the Zen kernel default to performance options; however at a later date it can be worth going over and learning about many of the features you can change and compiling in driver support just for your specific hardware.

A quick discussion on timer frequency: this option determines how frequently the kernel will address interrupts. On the one hand doing this too frequently slows down actually getting work done (the time spent checking is time spent not working). On the other it allows the kernel to be more responsive to events including input from the user. Hence a high timer frequency is recommended for use with real-time systems and workloads that prioritise interactivity; for example your average desktop. It should also help games especially in regard to input response (reduced input lag) and reducing frame rate jitter (providing smoother gameplay).

Now we’ll do something that’s probably going to be frowned upon by kernel developers but will ensure we get proper CPU tuning applied – edit the ‘Makefile CFLAGS’. This allows the GCC compiler to produce optimised code specific to your CPU’s architecture. There are different ways of doing this but a simple method is to run nano /usr/src/linux/arch/x86/Makefile press Ctrl+W to search and enter -pipe to find the correct line. In front of -pipe add -march=native -mtune=native .

This lets GCC determine and optimise for your CPU architecture on its own. However if you want to be specific you can specify your exact architecture; for example Sandy Bridge-based Core i7 CPUs from Intel should use -march=corei7-avx . To determine what flags represent your architecture see the GCC manual itself at GCC’s online docs.

Save the file and then do the following to compile the kernel:

make-kpkg clean

make-kpkg kernel_image kernel_headers

This will take a while but you can speed it up by spreading the workload across all your CPU cores. Since almost everyone has a quad-core chip these days simply run export CONCURRENCY_LEVEL=â€4†before the above commands. If you have a dual-core use a concurrency level of 2; for a hex-core fire it up to 6.

Once compiled you’ll find two new ‘.deb’ files in the /usr/src directory – install them and update the Grub boot manager like so:

cd /usr/src

dpkg -i *.deb

update-initramfs -c -k all

update-grub

And that’s it you’ve compiled and installed a custom optimised performance kernel! Reboot and enjoy. Note that if you’ve installed Nvidia or AMD drivers manually you’ll need to boot your kernel and reinstall them.

Finally if you want to compile vanilla kernel sources or those from Ubuntu the process is the same. To grab the kernel source for your currently running Ubuntu kernel first change to the /usr/src directory run apt-get source linux-image-$(uname -r) and then simply follow the above instructions to configure compile and install.

 

Separate X screens

If you’ve come from Windows it’s easy to forget that the GUI with Linux isn’t intimately tied to it. Linux makes it easy to run headless systems by simply not loading the X server – the basic framework all graphical desktops on Linux use. Conversely you can run more than one X server and have multiple independent desktops if you so desire each separate from the other.

It’s long been a gaming tweak for Linux to launch games in their very own X server thereby bypassing the desktop graphics framework of your desktop such as Compiz and Ubuntu’s Unity. The theory is that the screen has unrivalled access to the GPU and won’t be slowed down by running on top of a 3D-enabled interface. To some extent this has been true in the past although in recent releases of Ubuntu things have certainly improved.

Launching a game in its own X screen is simple enough – simply use the xinit command. For example xinit ./heaven -- :1 runs the Heaven benchmark we used in our testing in its own server. The -- flag specifies options that the server itself will follow while :1 tells the X server to launch in that display number. By default the first X server on the system is screen zero ( :0 ) and this is assigned in Ubuntu to the hotkey Ctrl+Alt+F7. The second screen :1 will be found under Ctrl+Alt+F8 and when you first issue the command you’ll automatically be taken to the new screen. You can then switch between your desktop and the full-screen game by simply switching between Ctrl+Alt+F7 and Ctrl+Alt+F8. You can have even more screens if you wish though there are limited hotkeys.

If you get an error along the lines of “User not authorized to run the X server†you need to make a quick edit for permissions. Run sudo nano /etc/X11/Xwrapper.config and change allowed_users= from console to anybody and then save the file.

You should note that running games from Steam this way requires you to either launch Steam using this method and then simply launch games from within Steam or specify the absolute path to the game when launching it. Alternatively since Steam is often required as a form of DRM you can launch a game directly via Steam’s ID system. For example to launch FTL:

xinit /usr/bin/steam steam://rungameid/212680 -- :1

Note the full path to Steam is required as your new X server doesn’t inherit the path of the shell. Don’t know what the Steam ID of a game is? Just right-click on a game in Steam and select to create a desktop shortcut; you’ll find the ID in there.

To close the X screen simply press Ctrl+C in the window where you ran xinit . Obviously some of this can be automated through scripts and who knows? Perhaps Steam for Linux will make it possible to launch games in their own server at a later date.

But does it make a difference? We had high hopes for this although in our testing it’s not really significant. The benchmark results were marginally higher when running in their own window but not so much that we felt a need to include them in the results. Still it may depend on which distribution you’re using and the underlying engine driving your desktop (we haven’t tested with KDE for example) so feel free to experiment yourself.

 

Benchmark results

You’ll see in the results the difference a customised kernel using the latest Nvidia 310.44 drivers makes on an Ubuntu 12.10 desktop. The open-source Nouveau drivers weren’t tested as they can’t currently match the performance of the official drivers for gaming. The test system is an Intel Core i7-3970X with 16GB of RAM and a GTX 680 4GB. The Windows tests are a reference point and were done using Windows 8 and the 314.22 drivers.

Looking at the Linux results first the custom kernel has a clear impact on performance for the Heaven and Valley benchmarks on the Basic preset by roughly 20%. The more demanding Extreme preset for both reveals a smaller lead but is nevertheless consistently faster. It also shows the difference between being GPU-bound and CPU-bound: in the Extreme preset the CPU is waiting for the GPU but in the Basic preset the GPU is rendering as fast as the CPU can feed it; here the custom kernel does a better job keeping it fed. This is especially true with regards to the all-important minimum frame rate when the benchmark is at its most demanding.

Team Fortress on Steam
Team Fortress 2 is the first of Valve’s Source-based games to be ported to Linux.

The Team Fortress 2 results also show the custom kernel to be faster but by a smaller margin. Testing at a lower resolution to ensure the system is CPU-bound doesn’t change the lead all that much (in fact variability – consistency of frames – appears to normalise) which is likely a result of the older Source engine upon which it’s based. The engine is so fast on modern hardware that even 1920 x 1080 doesn’t take a big hit.

Comparing Linux to Windows will see it taking the lead across the full set of benchmarks which is no surprise considering the maturity of the platform for gaming. However there are some noteworthy exceptions – at the Extreme presets for Heaven and Valley the custom kernel Linux maintains parity especially with regards to minimum frames. In fact it maintains these across the board indicating the average and maximum frames may be more a function of the maturity of the Linux Nvidia drivers.

For the Team Fortress 2 benchmarks Windows again maintains a higher average fps rate although Linux provides a more consistent experience with less variability and even more so with the custom kernel.

Test Results: Custom kernel vs Standard kernel

Benchmarks

Windows

Linux – Ubuntu kernel

Linux – Custom kernel

Heaven 4.0 (Basic preset)

Average fps

128

104

121

Minimum fps

32

25

33

Maximum fps

248

193

227

Heaven 4.0 (Extreme preset)

Average fps

41

40

42

Minimum fps

22

13

16

Maximum fps

90

99

100

Valley 1.0 (Basic preset)

Average fps

122

79

108

Minimum fps

39

34

38

Maximum fps

201

145

182

Valley 1.0 (Extreme preset)

Average fps

55

47

48

Minimum fps

26

26

28

Maximum fps

102

82

87

Team Fortress 2 (1920 x 1080)

Average fps

206

169

190

Variability

41

37

32

Team Fortress 2 (1024 x 768)

Average FPS

232

201

215

Variability

46

44

43

Note: For all scores higher is better except Variability where lower is better.

 

Game on

It can be fun to tweak and squeeze more performance from your machine but the fact that you can achieve a 20% performance boost by doing so is significant and something not possible with Windows. It also shows that Linux is ready for prime time as a gaming platform even if there’s still work to be done bringing its drivers up to date.

This is interesting to consider as it means any improvements in the drivers to match Windows’ maturity will only put Linux ahead. Hopefully we’ll also see gaming-oriented kernels and unique Steam for Linux features to make it easier to enjoy games on the penguin platform. And with the Steam Box on the horizon and the buzz it will generate we’re pretty sure it’s only a matter of time.

 

Playing nice

Another tweak you can use with games is to raise the CPU priority of both the game and the X server. On the whole modern kernels do a better job than they used to in making sure the X server maintains priority for desktop use but you can boost this and boost the game’s process using the renice command. First determine the process ID of the X server and your game; for example by running ps ax |grep X for the X server. Then renice the X server and the game’s process each using the syntax: sudo renice -10 [process ID] . It’s a good idea not to go below -10. There are other processes in your system some integral to its operation which will already have had renice applied during boot to ensure they have priority and may in fact be detrimental to performance if you prioritise a game above them. Generally though unless your system is already quite busy you shouldn’t have a need to do this. However it can be useful if you’re multitasking CPU-intensive apps in the background (folding or similar) where you can then prioritise a game to not be impacted by background work.

 

Nvidia tweaks

There are a number of driver tweaks you can make with the Nvidia driver to improve performance if your hardware supports them.

MSI interrupts

Linux supports MSI PCIe interrupts a more advanced and slightly faster method for triggering interrupts which some hardware will use by default. This can include network controllers sound cards and USB controllers. Nvidia cards also sport it but it’s not enabled by default as support depends on the system. However most relatively modern PCs should work fine. To tell the Nvidia driver to use MSI interrupts type sudo nano /etc/modprobe.d/nvidia.conf add the line options nvidia NVreg_EnableMSI=1 and then save. Reboot and to check your Nvidia cards now use MSI-X simply run cat /proc/interrupts |grep nvidia .

PCIe 3.0

If you’re using a late Sandy Bridge or Ivy Bridge CPU and 600 series or higher GPU you have access to the much faster bandwidth of PCIe 3.0. To enable PCIe 3.0 support simply edit the /etc/modprobe.d/nvidia.conf as in the MSI tip above add the line options nvidia NVreg_EnablePCIeGen3=1 and reboot. Note that if you’re using a Sandy Bridge CPU which isn’t officially certified for PCIe 3.0 you may suffer instability. If so simply revert the change.

SLI

While the Nvidia Linux desktop control panel is feature-rich it lacks the ability to enable SLI for those with more than one card. However SLI has long been supported under Linux and Nvidia’s own terminal-based configuration tool makes it easy to toggle. To enable SLI open a terminal and run sudo nvidia-xconfig --sli=auto . What this command does is it simply adds ‘Option “SLI†“AUTO‒ to the /etc/X11/xorg.conf file. Other options include ‘on’ ‘AFR’ ‘SFR’ and of course ‘off’ to disable.

  • Owen

    Since no one has seemed to notice, I will be the one to point it out. You spelled “Github” and “gitbut”.