64 Bit Development

Introduction

Note: these notes were written for Visual Studio 2003. Visual Studio 2005 has built in support for developing 64 bit applications so if oyu have the latest Visual Studio these notes are not needed.

I have a AMD 64 dual core machine running Windows Professional X64 Edition and decided to convert my T2 Texture Generation program to run as a 64 bit application. I found there was surprisingly little documentation on the Internet to help me and so the process was far from simple. By documenting my experiences in these notes I hope to help others wishing to write 64 bit applications.

The 64 bit Development Environment

The first step was to set up my development environment for 64 bit development. I use Visual Studio 2003 which has little built in support for 64 bit development.

In order to create 64 bit applications you need to install the latest Platform SDK from Microsoft (Microsoft Platform SDK for Windows Server 2003). The SDK, as well as having libraries for 32 bit programming, has 64 bit versions for AMD64 and IA64 (Intel) development.

Getting the correct library and header file paths set up in Visual Studio proved surprisingly difficult. I wanted the choice of developing 32 bit or 64 bit projects. While the platform SDK comes with command files to set up the correct paths they wipe out any other paths. Since T2 uses DirectX I also needed the DirectX paths setting correctly.

In the end I created two batch files, one for normal 32 bit development and one for 64 bit development.

32 bit development batch file

call “C:\Program Files\Microsoft Platform SDK\SetEnv.Cmd” /XP32 /RETAIL
call “dx_setEnv.Cmd” x86
start “” “C:\Program Files (x86)\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe” /useenv

64 bit development batch file

call “C:\Program Files\Microsoft Platform SDK\SetEnv.Cmd” /XP64 /RETAIL
call “dx_setenv.cmd” AMD64
start “” “C:\Program Files (x86)\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe” /useenv

If you want to use these you obviously need to change the paths according to your own set up.

The first line of each batch file calls the SDK provided command file to set 32 or 64 bit paths. The second line calls another command file that I created to append the correct DirectX path (DirectX provides both 32 and 64 bit libraries). This batch file is a bit large to display on this page but you can download it here: dx_setenv.cmd. The final line starts Visual Studio with the /useenv flag to indicate it should use the environment variables for its paths.

You can check that the paths are correct via the Tools / Options menu, Selecting Projects and VC++ Directories. My library paths for 64 bit development look like this:

C:\Program Files (x86)\Microsoft DirectX 9.0 SDK (August 2005)\Lib\x64
C:\Program Files\Microsoft Platform SDK\Lib\AMD64
C:\Program Files\Microsoft Platform SDK\Lib\AMD64\atlmfc

Now to create 32 bit applications I simply start visual studio with the 32 bit batch file and for 64 bit development I use the 64 bit batch file.

Configurations

Visual Studio 2003 does not support debugging 64 bit applications so I just created a release 64 bit configuration. You need to specify the target machine. This has to be specified in the linker command line box:

/machine:AMD64

For Intel development use: /machine:AI64

Another issue is that you cannot run the 64 bit version from within Visual Studio. You get an ‘Unable to start debugging’ message with: ‘The specified file is an unrecognised or unsupported binary format’.

This all makes developing 64 bit applications in Visual Studio 2003 a bit of a pain. You have lost the great debugger and so have to resort to log files and printf style output to track down bugs. One very useful setting is under C++ / General in the Visual Studio project property pages called ‘Detect 64 bit Portability Issues’. I would advise having this ticked for all development as I found it very useful in spotting cases where type size changes may cause issues. I also enabled asserts in release mode to help track down problems.

From 32 bit to 64 bit

At first glance the differences between 32 bit and 64 bit development seems quite small. All that is different is the size of some data types but this can lead to all sorts of problems! The data sizes are shown below:

Data Type32 bit64 bit
char8No Change
short16No Change
int32No Change
long32No Change
long long64No Change
pointer3264
enum32No Change
float32No Change
double64No Change
long double128No Change
size_t3264

As you can see a pointer and the size_t type are different sizes under 64 bit development. Note that under Linux 64 bit development a long is 64 bits.

New Types

The basetsd.h header from the Platform SDK defines a number of useful types like DWORD32, DWORD64, INT32, INT64, ULONG_PTR etc. For a full list see this MSDN page: The New Data Types.

Structure Sizes

The single biggest headache I had with converting T2 to 64 bit was structure alignment. The change in size of the size_t type also created some problems as I had been saving it to disk to indicate the size of some data to follow. Again loading the old data files was causing a crash as I tried to load 64 bits when only 32 had been saved. Doing a safe cast to a 32 bit type solved this problem.

One issue I had suspected would cause me problems but did not was the change in size of a pointer. This can cause issues if you store a memory address in a 32 bit data type e.g. an unsigned int. Fortunately I had not done that anywhere in my code but I have heard from others who have suffered from this.

Libraries

T2 uses some free libraries like the excellent zlib library. Some of these libraries used a lot of low level C code that needed converting to avoid the type size issues.

Results

Below is a table of timing results after converting T2 to 64 bit. This shows quite a significant speed improvement running the 64 bit version however there is one big caveat. The 32 bit executable is running in a 64 bit environment and so will run slightly slower than if it were running in a 32 bit environment. At present I have no way of testing these separately but I plan in on creating a dual boot system in the future which should allow correct tests. I still believe there is a significant speed increase with the 64 bit version.

Texture Creation

Project32 bit64 bit
Moody0.710.52
Island1High2.701.94

Texture creation involves a lot of passes through texture data. From the results the 64 bit version increased the speed by about 28%

Lightmap Creation

Project32 bit64 bit
Moody8.505.27
Island1High20.1010.17

Lightmap creation is a slow process as light rays are calculated between light sources and terrain, checking for obstructions in the way. From the results it can be seen that the 64 bit version increased the speed by as much as 50%. The larger the output, and hence the more calculations, the greater the speed gain.

Further Reading