Differences between console and PC development, Part 2
Compilers, debuggers and IDEs used for PC development are generally fairly mature and fully featured as they have been developed over many years and are used by large numbers of developers. Platform APIs and libraries are also usually fairly well tested and stable. By comparison, consoles generally have less mature tool chains and platform APIs, particularly early in their life cycle, and as a result developing on consoles has some problems that are not usually present on the PC.
PC developers are commonly advised to trust the compiler to do a good job of optimizing their code and to focus on algorithmic optimizations rather than low level optimizations. Compilers targeting x86 processors on the PC are mature and have many man years of work invested in their optimizers. Modern x86 processors are also quite sophisticated and use many techniques to get fairly good performance from code that is not optimally scheduled to hide latency or is branch heavy.
Console CPUs on the other hand are often non-x86 architectures and the compiler provided to developers will often not have had as many man years of work spent on its optimizer. Console CPUs are also often simpler than modern PC processors in order to keep costs down and are not as good at dealing with sub-optimal code. This means that trusting the compiler to do a good job of optimizing any code that's thrown its way will generally leave more performance on the table than it would on the PC. On recent consoles its usually possible to get fairly optimal performance without having to resort to writing assembly but only if code is written with a view to helping the compiler generate optimal code.
The compilers available to console developers, particularly early in the lifetime of a console, will generally have a particularly tough time dealing with more complex C++ constructs: features like templates, exception handling and virtual functions are often relatively more costly on a console than on a PC. This is partly a function of less mature compilers and partly a result of the relative performance of the console CPUs when dealing with some of the code constructs commonly used to implement these C++ language features. Historically it was not uncommon for the compilers available on consoles to not even support many C++ features, though more recent consoles usually have fairly complete support for the C++ language but with particular features having a higher than normal performance cost.
The relative lack of maturity of console tool chains compared to what is available on the PC also means that it is more common to find bugs in compilers, libraries and other parts of the tool chain. While on the PC it is very uncommon for an application level bug to trace back to a compiler bug and relatively uncommon for it to be due to a bug in common platform libraries, early in the lifetime of the console these are both possibilities that you have to consider when investigating any strange behaviour in your code. Again, compiler bugs are most likely to be encountered when using some of the more complex and less commonly used features of C++.
One bright spot in the tool situation on consoles is that developers usually have access to very comprehensive and sophisticated performance profiling tools, particularly once the console platform is established and has had a few years of development effort dedicated to its tool set. The tools for profiling CPU and graphics performance generally provide much more detail and much lower level performance information than is typically available to PC developers. While in many areas console tools are weaker than those available on the PC, this is one area where consoles generally have the edge.
Running games directly from read only media on console vs. hard drive on PC
PC games are almost always intended to be installed to the hard drive and load from this relatively fast storage device when played. Console titles on the other hand have traditionally been designed to run directly from the media they are shipped on - generally an optical disk on modern consoles. Some console games will use or occasionally even require a hard drive to improve load times but this is still the exception rather than the rule. Console optical drives generally have lower bandwidth (how fast sequential data can be read off the disk) and much slower seek times (how long it takes to move around the disk to find an item when reading non-sequential data) than a hard drive. The performance characteristics of optical media vs. a hard drive mean that console titles generally have to put a lot more effort into ensuring they load game data efficiently than PC titles in order to achieve acceptable load times.
The relatively slow seek times of console optical drives mean that it is important that game data should be arranged on the disk so that it is loaded in large sequential blocks with as few seeks as possible. Compression can be useful to speed up loading by reducing the amount of data that must be read as well, though the additional memory and CPU cost of decompressing the data on load must also be considered. Console titles will often have an automated pipeline for processing game data into an efficient format for loading. A common technique used when loading game data on consoles is to process the data into a form that can be loaded straight into a block of memory and used directly after a quick fixup process for any pointers. For games that have a streaming continous world rather than a level based progression there are additional challenges and complexities.
Details of some of the common techniques for efficient loading on consoles will be the topic of a future post.
Specialized hardware on consoles vs. more general purpose hardware on PC
Consoles usually have some fairly specialized hardware designed to make them a cost efficient system for their primary purpose of running games. PCs on the other hand are used for many different tasks and have more general purpose hardware reflecting their general purpose use. In order to get the most out of a console it is important to understand the specialized hardware and apply it effectively. This task is made easier by the detailed information on the hardware that is generally provided by the console manufacturers to developers but sometimes developers have to figure out a certain amount for themselves.
Modern games need to do quite a lot of heavy duty floating point number crunching for things like physics, 3D graphics and animation. Modern consoles have hardware designed to provide a large amount of raw processing power for floating point calculations but in order to provide this power at a reasonable cost they make design choices that require programmers to use this hardware in the right way to get good performance. Whether this number crunching power is provided as SIMD/vector extensions to the CPU instruction set, special purpose vector co-processors with their own unique instruction sets, through programmable units on the graphics processor or through some combination of these, it is generally accessed through non-standard extensions or APIs which developers must familiarize themselves with. While modern PCs also provide SIMD instruction sets and programmable GPUs with large amounts of floating point processing power, they are often less heavily used by PC games than by console titles.
Consoles often provide other specialized bits of hardware that can provide a significant performance boost when used appropriately. Things like specialized hardware for decompressing audio or texture data, special purpose fast memory for frame buffers or 'scratch buffers' for CPU calculations, special fast data paths between different processors or different memory areas, or custom CPU instructions geared towards specific operations common to games. Developers who know the details of the hardware available on the platform can use it to squeeze more out of the system than developers who don't utilize the unique features available. Sometimes clever use of specialized hardware can allow console developers to do things that are not possible on a PC unless it has general purpose hardware that is significantly more powerful than the general purpose hardware available on the console.
Cross compiling on consoles - targeting a different CPU architecture
Cross compiling is familiar to any developer who is building software on one system that is intended to run on a different system. PC developers are usually used to building and running their game on the same PC but when developing for consoles it is normal to develop and build the code on a regular PC and then transfer it to the console to run and debug it. This has some implications that can trip up developers who have not targeted a different architecture before.
One common source of difficulty for PC developers transitioning to console development is endianness differences between the host and target architectures. PCs are little endian but many consoles are big endian. This means that binary data created on the PC but intended for use on the console must be endian swapped at some point. This can entail quite a bit of work for a codebase that generates a lot of binary data and wasn't written to handle endianness differences.
Any code that makes non-portable assumptions about memory layouts can also cause problems when dealing with cross platform development. This is most often a problem when trying to port an existing PC codebase to consoles. Unsafe assumptions about data layouts and packing in classes or about details like vtable layouts or alignment requirements can cause code that worked on PC (but was actually relying on undefined behaviour) to blow up in nasty ways on other platforms.Conclusion
I've tried to cover what I think are the most important differences between console and PC development but I've only skimmed the surface of many of these issues and future posts will delve into more detail on some of them. I've probably neglected to mention some other important differences as well but I hope this post will at least give a broad overview of some of the challenges to expect when moving from PC development to console development.