So as promised here's a more detailed explanation of the complications of 64 bit software development, along with a conclusion at the end wrapping up my thoughts on this matter. I hope I don't end up making a too long post that becomes boring to read.
Key concepts
Here I'm introducing some key thoughts to keep in mind, while you read what's below:
- 64 bit operating systems can run 32 bit applications. But 64 bit applications cannot run under any circumstances, except one (1), on 32 bit operating systems. To be clear, if I develop a 64 bit only application, it cannot install on users who are still running 32 bit operating systems (be it Windows, Linux, or Mac OS X to name the most prevalent).
- WOW64, the 32 bit emulator for 64 bit Windows cannot execute 32 bit device drivers or run certain 32 bit applications that try to access pure 64 bit processes. This means for instance that 32 bit add-ons for Internet Explorer, Office, Windows Explorer, an any other software that expose a 64 bit plugin or extension architecture, won't work. What this means is that 32 bit support on 64 bit Windows is actually limited.
- All major operating system vendors still offer 32 bit versions. Microsoft, Apple and the Linux kernel community. One of them removing support for their 32 bit OS branch may, or may not, have an impact on users decision to move to another operating systems. Also, each one of them in their own different ways still face the occasional 64 bit support issue that doesn't exist under the equivalent 32 bit version. This may or may not work as a scare to some users or decision makers working under mission-critical environments.
Introduction
This post concentrates only on the complications of 64 bit programming and on the effect it has been having on the software development "community", from the hobbyist at home to the major software development company.
Most of this is written from my own experience and my observations of the industry. As such, most of this is academic ramblings at best, flat out wrong at worst.
Why 64 bit development?
Let us turn the relevant question up side down. Instead of asking ourselves why are we still doing 32 bit applications, I'll ask what's advantageous about 64 bit development.
We know the advantage of 64 bit platforms. We can have more memory. That's a pretty big deal right there in these days when the complexity of what can be done on a computer means larger programs demanding access to larger portions of our memory. 64 bit computers are for instance today pretty much the requirement to run virtual machines, to host servers or to satisfy power users who require an hefty number of heavy-duty applications to run at the same time on their computers.
Conversely, the question on whether 64 bit applications run faster than their 32 bit counterparts is purely circumstantial and has no bearing on a discussion that we want factual. Some applications will work faster (applications making heavy use of the processor registers), others will have no meaningful effect (applications which don't). Some will work slower if the developer didn't do their job correctly. Which, unfortunately many don't. So for all purposes, the address space of 64 bit computers is the real and palpable advantage here. The rest is too debatable and incidental for being of any use.
Does this necessarily translate to a desire in developing for the 64 bit architecture? It depends.
As far as software developers are concerned, the 64 bit platform offers them two advantages over the 32 bit one. They can work on an extended allocated memory space for their applications. And they can work on larger in-memory data sets.
This is the rundown of of application memory allocation limits on both architectures, in Windows:
32 bit
- Static memory: 2GB
- Dynamic memory: 2GB
- Stack memory: 1 GB
64 bit
- Static memory: 2GB
- Dynamic memory: 8TB
- Stack memory: 1 GB
It's interesting to note that only dynamic memory benefits. This is by design of Windows itself. Maybe one day, Microsoft will implement a new PE (Portable Executable) format that implements 64 bit fields. But until then, no dice. And because that format would be incompatible with 32 bit executables, 32 bit backwards compatible on 64 bit windows as it exists today would be more difficult.
In any case this is a tremendous advantage to programs that either require large amounts of memory or that wish to work with data sets larger than 2GB.
This is the real advantage of 64 bit development under Windows. One that is crucial for the evolution of certain industries like Gaming (as discussed on this thread), but also some scientific software, server software (including obviously, databases), virtual machines that have been experiencing a boom in later years, video and imaging software and and even on certain key businesses administrative tasks. For instance, it's not unknown the need of certain businesses to work with very large Excel sheets, above the 2 GB boundary.
So, why not 64 bit development?
Well, if you don't require more than 2GB allocable memory in your application, you don't really need to develop for the 64 bit architecture. What's worse, doing so can be a problem under certain circumstances, adding a new set of concerns to an already long list of programming challenges.
The reality of it all is that 64 bit programming translates simply to access to more memory. It isn't a fundamental architectural event like the 32 bit revolution was. It finds its proponents on those areas that can take real advantage of it and that depend on it for their evolution. Every other programmer can go pretty much "meh!" on it without fear (for now, at least).
This has the disadvantage that, contrary to most of the history of 32 bit adoption, 64 bit has fragmented the developer community between those that need to develop for it and those that don't. Those that don't, usually delay their adoption and keep doing 32 bit development, unknowingly extending the period of 32 bit support hardware and operating system vendors need to give to the 32 bit platform.
The question is still unanswered though. Why not just do the bloody program as a 64 bit executable?
- 1st problem: Porting software can be a lot of work.
For years developers know that "if it works, don't change it" is a good maxim. This is a culture that ensures good, working and dependable software. But it's also the reason why so many legacy systems exist to this day. It's a two-sided stick. With one side you thrust bugs and all the problems that could arise from messing with code that just works, with the other side you are poking yourself in the gut and forcing the industry to somehow maintain, or have to deal with legacy systems. From Internet Explorer 6 to old 16 bit systems still operating on companies, we see this culture operating on both the consumer and developer markets.
The reason is that rarely a program can be ported to a newer architecture without any work and without failing or introducing new bugs. The work involved in dealing with the new problems is often not acceptable when the work involved with maintaining the old system is too much already. On the other hand, the system in question (here meaning the combination of hardware and software) can be a mission-critical system and one cannot afford any risks, particularly on cases where it's difficult or takes a whole lot of time to do proper testing.
64 bit development introduced changes to the programming data models and function convention calls that can easily introduce new bugs when porting 32 bit programs to 64 bit platforms. Bugs that can be hard to spot. Despite all the documented best practices, many developers take for granted the size of a variable in memory and perform operations (bit shifting and even simple integer arithmetic) that will fail when the program is compiled in 64 bit. Depending on which compiler they use and how it is setup these errors can creep in in an invisible fashion and result in a program crashing (which is good) or producing wrong results (which is disastrous and the absolute worst that can happen).
Likewise, the changes to function convention calls in x86-64 means that many DLLs or executables that communicate with different programming language DLLs, or have been designed to be easily ported to other systems, may require extensive changes to the source code.
- 2nd Problem: Available input data formats and boundaries
The x86-64 architecture poses a problem to systems that rely on existing data that has been tailored specifically for the 20 year old 32 bit architecture. If data exists on a system out of the developer control (another DLL, a database, a file) that has been formatted according to the specifications of a 32 bit typical integer or that makes use of data sets using typical 32 bit boundaries that are not longer correct under 64 bit development, more or less complex data marshaling routines have to be developed to correctly read and write to this, now old, data format. Many of which can have an impact on application performance.
Many examples exist of this problem. A common one among companies is the Jet Database Engine that powers Microsoft Access and is was (and is) used extensively on Visual Basic projects. Until last year, Microsoft didn't make available a 64 bit version of this engine and WOW64 didn't support it either. 64 bit applications couldn't access mdb files. The only way was to use third-party marshaling software that would be installed under WOW64. Software that meant a decrease in database access performance.
- 3rd Problem: Library (or API) availability
This is particularly problematic to in-house software development or developers working with no longer maintained API or libraries, or older versions for compatibility or stability reasons.
A source Library is a collection of code that gives developers manageable access to certain programming language features or facilitate the development by providing pre-written classes, routines and specifications. For the purposes of this debate consider Libraries as just a form of an API, if you don't want to care about the actual differences.
The matter of fact is that Libraries and APIs still exist in great numbers with no, or limited, 64 bit compatibility. Because these represent key components of the development stack, it's simply not possible to develop a native 64 bit application accessing these libraries without once again incurring in performance-wise expensive data marshaling.
Too many examples exist once again. To pick one -- and to get away from Windows for a bit -- consider the Carbon API for the Macintosh. Developers who have been relying on it, will need to migrate to Cocoa if they wish to develop for 64 bit. Only the GUI portion of the old API is supported in 64 bit. What's worse, Apple doesn't provide C/C++ compatibility between the 64 bit versions of Mac OS X and Cocoa. So former Carbon application developers need not only to learn about the new Cocoa API, but also learn to program in Objective-C. Want to know why Final Cut Pro X had less features than the former version? Well, that's the more than likely reason since the application was entirely re-written for the Cocoa API. We are talking about having to rewrite in an entirely new programming language extensive areas of the application, if not everything.
This is an extreme example of what can go wrong with the lack of library or API support, but one that illustrates well why some developers may be so resistant to the idea of moving to 64 bit development.
- 4th Problem: Porting software on diverging data models
64 bit development introduced a new problem to those wishing to develop software for multiple platforms (usually Windows, Linux and Mac). Until now the most used data type had the same size on all systems. Not anymore. Windows 64 bit uses the LLP64 data model that attributes a 32bit size to the integer data type. Unix-based systems use the LP64 data model, on which integers are 64 bit in size.
The complexity of porting 64 bit software resides on the fact that Windows 64 bit now requires the long long data type to store pointers and other data entities that represent 64 bit values, whereas the good ol' integer remains the data type for these in Unix-like systems.
Because historically developers have consistently make the mistake of relying on data types sizes (despite all the well documented best practices) to perform many arithmetic or bit shifting operations this rarely means just changing the variable data type and recompile. More often than not, this means carefully going through the code (code that was likely written by someone else or many years ago) trying to find hard to spot bugs that will be introduced with the change.
Of note also the fact this is a problem even if one is not porting software to other systems, but simply porting 32 bit code to 64 bit on the same operating system. Here, Linux and Mac developers have it the worst because their integer data type has been silently changed to a new size, while Windows developers may relax, having to concern themselves only with the fact their pointers need to change to the long long data type. They must however check all their pointer arithmetic just in case. There's a whole lot of bad practices there too.
Conclusion
This is an addendum to my previous post on this thread. Here I try to explain the complexities of 64 bit development. Particularly on what concerns porting 32 bit code to run on the new x86-64 architecture in
long mode (as a native 64 bit executable).
For the impact this has on the requirements on vendors to keep supporting 32 bit versions of their operating systems, see that post.
The matter of fact is that 32 bit development is still a in-your-face reality. It's going to take still some time. The transition cannot be imposed by an operating system vendor like it was before with the 32 bit adoption.
Thankfully we are walking that road. And every new day is one day closer to that goal. It's only when consumers and software developers give the signal their adoption of the 64 bit platform is complete and only a fringe still hold on to old practices, that vendores will feel it's the time to pull the plug.
If there is one corollary to all this, that is:
It's not because Windows stops developing the 32 bit version of their operating system that developers will stop doing 32 bit software. Exactly because Windows 64 bit is mostly 32 bit compatible. It won't change anything. The issues with 64 bit development are real and impose themselves on many developers and businesses. It's developers that need to deal with the transition and eventually stop developing 32 bit applications. At the very least start supporting 64 bit versions of their software.
It's a bit like expecting the death penalty will stop crime. You stop crime by dealing with the criminal directly.
Want to argue with anyone? Argue with your favorite game developer, if they don't give you a 64 bit version of their game.
(1) A 32 bit operating system running under a 64 bit processor capable of legacy mode (Intel and AMD, for instance) and that supports hardware virtualization, can install a 64 bit Guest operating system in a virtual machine and run 64 bit applications natively (in the actual hardware).