Switching to Linux: A Windows developer’s view

September 14th, 2009

A few weeks ago, I switched my development environment from Windows to Linux, on a project which was developed so far on Windows only. In this post, I want to describe the issues that brought me to this switch, a short overview how I did the actual port, and some observations on Linux for developers. This is the first post in a series of at least two, the second post will describe the tools I use on Linux right now.

Background

The project I’m working on is written in C++, with some Python tools mixed in. My original development environment was Visual Studio 2005 on Windows XP. This is already the first issue: Updating Visual Studio or Windows is not trivial, as both the OS upgrade as well as IDE updates require new licenses, and especially in companies new versions are not bought immediately.

The problems became apparent when I tried to multi-thread parts of the application. At the core, it’s doing a lot of number crunching, in small work blocks which can be processed independently. As I couldn’t use OpenMP due to dependency issues (a 3rd party library could not be linked when OpenMP was enabled), I was threading manually. Unfortunately, the application had to allocate some memory in each thread, and as it turned out, the scaling on XP was catastrophic. While I did get a speedup from 1->3 cores, it became slower from 3->4 – clearly, I was hitting some issues with either the scheduler or the memory subsystem, as my code didn’t have any I/O in it.

A quick try on Vista showed that the same application ran more than twice as fast, but unfortunately, I couldn’t install my IDE on Vista as well, and developing on Windows XP and testing on Vista was out of question. Again, with a free IDE, the change would have been no problem (and the express editions don’t have x64 support*, nor OpenMP, more on this later. * See below for an update!).

On the other hand, getting a recent Linux with a recent compiler was not a problem. With Wubi, Linux can run side-by-side with Windows while giving you a full Linux based development environment. Running side-by-side is especially important when you’re in a corporate environment, as you usually cannot simply erase the disk and install Linux without making the IT angry.

Linux

I used Wubi, with the Kubuntu flavour, as I like the KDE environment a bit more than GNOME – especially as I use Qt for UI development now. Specifically, I used Kubuntu 9.04 x64, while I used a x86 Windows XP previously.

Porting

I started by checking out the code from SVN, so no problems here. Even though the application was written in standard C++ and didn’t depended on Windows-specific functionality, it was built using Visual Studio project files and used a few WinAPI calls. As a first step, I ported everything to CMake – something I could/should have done on Windows already. With CMake, I was able to quickly convert one project after the other, and immediately check for compile errors. This proved to be the best way, as I never came into the situation where I would get huge amounts of compile & linker errors at the same time; I had that when I moved an already CMake based project from Windows to Linux and tried to get it running in its entirety. During porting it’s best to port on subproject at a time, even if the project is originally using a portable build system.

As I mentioned, I used explicit threading on Windows, which I replaced by OpenMP on Linux. Now I could also throw out all configuration stuff for threading; among other things, I wouldn’t have to reduce the priority of my application on start-up – this was necessary on XP, as the machine would become unresponsive during processing otherwise. Boost.Threads might have been a valuable alternative here, but OpenMP is well suited to the kind of loop-parallelism I had in my code, and even simplified it compared to the explicit splitting/execution I used previously.

For graphics, I was already using OpenGL. As I could easily get the nVidia binary drivers running, I had no trouble on this side. Overall, it took me half a day to port, including the time to set up the Linux installation.

Results and some thoughts

The net result is interesting: The same application is running 5-10x faster now when using all four cores, so porting to Linux was really worth the hassle. I assume that with Visual Studio 2010, running on Windows 7, I would get similar performance, but the key point to take with you here is: Getting your stuff to work on Linux only costs you time, and not too much if you are a bit careful. Using CMake on Windows (or another portable build system), writing more or less clean C++ and using portable libraries makes porting to Linux easy, and the switch itself is not too complicated. At the moment, the tooling on Linux is reasonably comfortable (more on this in the next post), and the “pain factor” to switch from Visual Studio to for instance KDevelop or Eclipse CDT is no longer there.

Actually, the switch is so simple that Microsoft should get concerned. For instance, I have been developing mainly on Windows since several years, and I occasionally tried Linux, but I never did a complete switch due to various smaller and bigger problems. However, since 1-2 years, the Linux desktop, together with the tools, is good enough to provide some real benefit, especially if you cannot access the latest Microsoft products. Microsoft used to have the best developer tools by far, and quite stable APIs, which were in my opinions the corner stones of their success. However, they’re changing APIs now rather quickly (WinForms? WPF? WinAPI?), they provide new platforms which require rewriting your applications (I’m still waiting for an application like AutoCAD which has a C# UI and a C++ backend), and the tool release cycle is simply too long – waiting 2 years to get a compiler bug fixed is just ridiculous.

On the other hand, developing on Linux means you have an extremely stable API (POSIX isn’t going to be replaced with PoseFX, for instance), the UI side is rather clear (GTK or Qt, you choose), and the tools are getting better as well (GCC and LLVM are getting better quickly, and installing a new GCC does not require buying a new license). If Microsoft does not turn around the ship with Visual Studio 2010 and some clear statements on the APIs, I assume that more and more developers will find that Linux can be also a very nice environment. Again, more on this next time!

[Update] A few notes, as this article is getting a lot of attention and there are some misunderstandings. Regarding the library, I had access to the source, and I could have built it on Windows — it’s simply very time-consuming, as it depends on many libraries like zlib, which I would have to compile with the new settings on Windows as well. Getting these dependencies on Linux is obviously much easier.

OpenMP vs. manual threading: This did not improve the performance compared to the manual threading, but it was a nice bonus as it cleaned up the code a bit. On Windows, I could not use OpenMP due to link issues. The other bonus came from the switch from x86 to x64. Finally, the Linux memory allocator is much better in multithreaded environments, and this was the biggest performance improvement. In total, the application runs several times faster now, without changes on my side.

Summary: In this particular case, the switch to Linux took me just a few hours, while the benefit for me was rather big: Improved performance, and less hassle with dependencies. The drawbacks — getting used to Linux, different tools — are out weighted by the advantages for me; and that’s the main point of this blog post. I was surprised how easy it was to switch from Windows to Linux completely on this project; as I expected a lot of problems (like for instance, not being able to get the stuff running at all!)

Things might have been different if the library and the dependencies would be easier to build on Windows, and I would have gotten access to a new Windows version/new compiler version, but this is simply how things turned out, and I don’t miss my Windows setup at work.

[Update] The x64 editions of Visual C++ Express require some setup to support x64, but it is possible to add x64 support manually using the compilers from the Windows SDK. Check out the official C++ Express feature list and a guide how to enable x64.

Anteru Programming

DirectX SDK (August 2009) released

September 10th, 2009

Finally the DX SDK August 2009 has been released, which contains the RTM version of DirectX 11. Moreover, it also brings back the effects framework for DX11, which was missing in the March SDK. Grab it at the Microsoft Download Centre while it’s hot.

Some things are still not supported, especially PIX is not able to debug compute shaders at the moment. On Vista, it may require a patch to work (KB971644), which is not up yet, so you should run Windows 7 if possible.

[Update] The update for Windows Vista can be now downloaded. It’s actually a larger platform update (and currently beta), which also brings the Scenic Ribbon from Windows 7 back to Vista. Took me a few tries before the download centre would display the update (previously, I got “page not found”), so be patient.

[Update] The update is not working on localised Vista versions, I could install it on an US Vista, but not on a German one. Specifically, it fails to to install “Windows6.0-KB971512-x64″, which contains the d3d11.dll (among other things). I’ll update this post again if I get it working, in the meantime, use an US Vista. Setting the language options to English (US) is not enough.

[Update] Got two confirmations from Microsoft, it is indeed only working on en_US Vista installations. The final release will work with localised versions as well. That’s a annoying, as I don’t get why I have to wait for potentially weeks just because I cannot change my Vista locale.

[Update] The final version has been released.

Anteru Realtime

Using CMake to build a Qt application

September 7th, 2009

CMake is a really great build tool, and it makes it very easy to use a lot of libraries with it. For example, CMake has a built-in module that helps you to set up a Qt project. Unfortunately, it’s a bit tricky to get started with it, so this post provides you a quick getting started guide to create a typical Qt application. For most of the time, we have to deal with three Qt related file types (besides .cpp and .h): .qrc, .ui and .h/.cpp files which contain Q_OBJECT enabled classes.

Resources

.qrc contain resources, and are the easiest to handle. The Qt resource compiler (rcc) simply creates a single .cpp file, and puts all resources as static arrays into it. The corresponding CMake function is QT4_ADD_RESOURCES. The first parameter is the output, which you have to add to your source file list.

UI

For the .ui files, the UI-compiler has to be called first (uic) which generates a header file; this header contains all the logic to set up your user interface. You include this generated header in your source files, and use it to display the UI. How does this look like in practice? Well, let’s assume we have a file “testDialog.ui“, which contains the UI, and we want to implement a dialog using this UI. We create a custom class, for example, TestDialog, which is derived from QDialog. This class is put into TestDialog.h/.cpp, and may look like this:

#ifndef MY_TEST_DIALOG_H
#define MY_TEST_DIALOG_H

#include "ui_TestDialog.h"

class TestDialog : public QDialog
{
    Q_OBJECT

public:
    TestDialog ();

public slots:
public signals:

private:
    Ui::TestDialog ui;
};

#endif

The “ui_TestDialog.h” file is generated by the user interface compiler (uic), using the QT4_WRAP_UI command. The output is directly into the output folder, so you should add INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) to your project file — otherwise, the files won’t be found. In your dialog constructor, you can init the UI now using:

ui.setupUi (this);

QObject derived

Running the meta-object compiler for QObject derived classes is similar to resources, you add QT4_WRAP_CPP in your CMake file, and just add the generated files to your source files. The input for this function is the header of your class, not the implementation — even though it’s called QT4_WRAP_CPP, you must pass the file containing the declaration; this is usually the header. Those files contain a bunch of functions which are needed for the Qt meta-object system. These are stand-alone .cpp files that you usually never have to look at.

Notes

I usually wind up including all generated files to my project, so I can debug into them. To generate clean project files for Visual Studio, you should use source groups (check out the SOURCE_GROUP command) — be careful though, as the files end up in the current build directory. That’s it, you should be ready to create Qt applications with CMake! Feel free to ask questions if something is unclear, so I can update the post.

Anteru Programming ,

Carmack’s 2009 keynote

August 31st, 2009

Even though QuakeCon 2009 is over since quite some time, I just got around to watch the keynote a few days ago. At first it is a bit slow-going when Carmack starts how great the guys at Bethesda are, and other business stuff. Obviously, they are still quite free even though they have been bought, but the future will tell whether this deal is all that great as they talk about it at the moment.

Technical

There’s less technical stuff than usual in my opinion, especially no forward-looking stuff at all as Carmack didn’t have time for R&D yet. He still believes that voxel rendering is the way forward, and while I tend to agree with this somewhat, I don’t see at the moment how to make a game engine on a voxel renderer right now (and going hybrid with triangle and voxel rendering is an interesting problem). Besides this, he mentions that the virtual texture mapping stuff took quite a lot of time and it’s still not as usable as the artists would like it to be. The updates are still taking a bit too long, and by looking at their SIGGRAPH presentation this is obviously down to the fact that they use extreme compression and lots and lots of trickery to improve runtime performance, trading off edit time for it big-time. This is for example totally different from what Crytek does, where they try to minimise offline processing as much as possible (no precomputed lighting for example, while Rage uses a radiosity solution for all the outdoor lighting).

Near the end, he also talks a bit about threading game code and scripting languages. At id, they want to keep the game code single-threaded so that programming and debugging becomes easier, and move all computationally intense systems to threads (collision detection, etc.). What makes me wonder is that he says that they prefer C++ code over script code for easier debugging, which sounds kinda weird at best.

Another interesting tidbit: They use Oracle Enterprise as the database backend for Quake Live, and Carmack complains that this is extremely expensive, so that scaling by increasing the database cluster was out of question when they hit the first performance problems. Weird that they didn’t choose PostgreSQL, as I don’t see any advantage of using Oracle for this (after all, this is not a bank account system …). On the other hand, Oracle seems to be popular among game developers, as World of Warcraft is also likely running on Oracle (at least they always look for people with Oracle experience).

Production stuff & mobile division

Most of the talk focuses on production issues, which are interesting to hear for someone who is not working in a game company. For Rage, they really try to make sure that everything is working right – they spend a huge amount of time on tiny details, to make sure that the game is really polished.

A big chunk of the keynote is devoted to the mobile division at id. They seem to be re-use lots of their old games with pretty good success, and Carmack seems to like this small-scale development a lot. For the future, they are going to focus on the iPhone, which is a bit unfortunate in my opinion as very nice devices are coming out with Linux – the Nokia N900 for instance (in this particular case, running Maemo – a mobile Linux which I expect to be used broadly in the future).

Summary

Pretty interesting summary this year, if you want to watch it on your own, check out the video coverage on Quake Unity. No need to take the HD version though; could have been a pod-cast just as well.

Anteru General, Graphics, Programming