Coding Horror

programming and human factors

Transfer Mode Downgraded

I noticed when I was burning the Vista RC1 DVD that ..

  1. It took forever, eg, nearly an hour
  2. My PC was very sluggish during the burn

I began to suspect something was awry with the IDE controller that the DVD-R drive is connected to. I navigated to Device Manager, expanded the IDE ATA/ATAPI controllers tree node, right-clicked the Parallel ATA Controller node and selected properties.

And what do I find on the Secondary Channel tab? Sure enough, Transfer mode downgraded.

Transfer mode downgraded: the transfer mode for this device was set to a mode lower than what it is capable of because of excessive transfer errors to the device. This will cause a loss of system performance. Please check the cabling to the device and verify an 80 conductor flat ribbon cable is used for Ultra66 and higher transfer modes.

This behavior is, of course, by design. Microsoft automatically downgrades the transfer mode on a Parallel or Serial ATA channel after receiving more than six CRC errors on that channel. At least you can see when this has happened-- Microsoft provides the little yellow alert pictured above, along with some alerts in the system Event Log.

CRC errors are very dangerous for a hard drive-- that means you've got some serious hardware problems. But for a DVD or CD drive, it probably just means you tried to read a scratched disc. You can override this obnoxious behavior in the registry.

I flipped the switch back to "Let BIOS select transfer mode", rebooted, and I was on my way:

BIOS-selected Ultra DMA 2 transfer mode for a DVD/CD-ROM

However, depending on what Windows XP has decided to do here, you may need to uninstall the channel (just right-click it in Device Manager to do this). Don't worry, uninstalling won't cause any problems. Just reboot and the channel will be redetected with default settings.

To illustrate how important proper PATA/SATA transfer mode settings are, here's how long it took to burn a Vista RC1 DVD on my PC before and after:

in PIO mode: 56 minutes.
in Ultra DMA 2 mode: 4 minutes.

Friends don't let friends use Programmed I/O Mode.

Discussion

External Hard Drives

Now that Vista Release Candidate 1 is available, it's time to start playing with it. I'm tired of using my current legacy operating system. Testing Vista probably means I'll probably be booting from an external hard drive.

external-hard-drive.jpg

External drives have been available in Firewire and USB flavors for years. An even better option is to route your internal SATA connectors to the back of your PC and plug in the external hard drive using its native SATA interface for maximum performance.

external-sata-bracket.jpg

The performance difference between USB, Firewire, and SATA can be dramatic. Compare these throughput numbers:

SATA II55 MB/sec
SATA54 MB/sec
IDE54 MB/sec
Firewire 80041 MB/sec
USB 2.035 MB/sec
Firewire 40029 MB/sec

It's also possible to use plain old internal SATA connectors to connect external drives, but most external brackets convert the internal SATA connectors to External SATA connectors or "eSATA". These are basically just more robust, better shielded versions of regular SATA connectors. Do be careful which connector you get, because they have different shapes and aren't interchangeable.

eSATA connections are great for desktops, but most PC laptops typically only have USB connectors. Fortunately, there are enclosures that offer the best of both worlds-- USB 2.0 and SATA connections for 2.5" notebook hard drives, as well as 3.5" desktop hard drives. Just buy the enclosure and add a hard drive of your choice.

If you want maximum performance from your external drive, I recommend choosing something from the 10,000 RPM Western Digital Raptor series. I've switched to Raptors as my system drive on both my work and home PC, and the difference is quite noticeable. They're also much quieter and cooler than I expected for such fast drives. The Raptors aren't cheap, but you'll see the value of these drives the first time you boot up.

Discussion

Computer Languages aren't Human Languages

Though I've become agnostic about the utterly meaningless non-choice between VB.NET and C#, the inherited syntax of C leaves a lot to be desired, in my opinion. And not just in the case sensitivity department. Daniel Appleman, in his excellent e-book, VB.NET or C#, Which to Choose?, concurs:

Here I risk stepping on some toes, because language syntax is very much a religious issue with many programmers. Certainly we all tend to prefer the language syntax we are familiar with, and C++ and Java programmers will certainly find a great deal that is familiar in C#.

It should also be clear from this section that the differences between the two languages in this area really are minor. Both have virtually the same functionality.

Nevertheless, on the subject of object syntax, I must give the win to VB.NET. Just look at the inheritance declarations:

public class BClass: AClass, Iint
Public Class BClass
Inherits AClass
Implements Iint

Look at the words used to control inheritance:

abstract, sealed, virtual
MustInherit, NotInheritable, Overridable, Overrides, Shadows

When it comes to looking at code and understanding what it does -- especially later on when the original developer has left and some young programmer right out of college has to figure out what it does quickly to solve some obscure bug or add a new feature, which one is going to be easier to understand? Visual Basic .NET.

Although I do agree with Appleman on this point-- void is for sci-fi geeks; nothing is for human beings-- in the big scheme of things, it's barely relevant. If the success or failure of your project hinges on the minor syntax differences between two virtually identical .NET languages, you have much deeper problems than choice of language.

Although the tradeoff between verbosity and succinctness is worth considering, there are other risks here. Computer languages, however verbose you make them, shouldn't try to become proxy versions of spoken languages. I've never worked with AppleScript before, but it fell into this trap in a big way. Here's a sample bit of AppleScript code to illustrate:

tell application "Mori"
tell front document
set a to first item of selection
set b to second item of selection
set a's note to (a reference to a's) note & (a reference to b's note)
end tell
end tell

Looks almost like a paragraph, doesn't it? John Gruber calls AppleScript the English-Likeness Monster:

The idea was, and I suppose still is, that AppleScript's English-like facade frees you from worrying about computer-science-y jargon like classes and objects and properties and commands, and allows you to just say what you mean and have it just work.

But saying what you mean, in English, almost never "just works" and compiles successfully as AppleScript, and so to be productive you still have to understand all of the ways that AppleScript actually works. But this is difficult, because the language syntax is optimized for English-likeness, rather than being optimized for making it clear just what the f**k is actually going on.

This is why Python and JavaScript, two other scripting language of roughly the same vintage as AppleScript, are not only better languages than AppleScript, but are easier than AppleScript, even though neither is very English-like at all. Python and JavaScript's syntaxes are much more abstract than AppleScript's, but they are also more obvious. (Python, in particular, celebrates obviousness.)

AppleScript's natural language metaphor turns out to be more of a curse than a blessing.

Some languages are arguably more readable than others, of course, but keeping the goal of clarity front and center is far more important than bickering about relatively meaningless language choices. You can write FORTRAN in any language, so choose whatever language you're most comfortable with and optimize for making it clear what the f**k is going on.

(I thought about letting the f-bomb drop in this post for emphasis, but my fireball isn't quite as daring as John Gruber's.)

Discussion

Game Player, Game Programmer

Greg Costikyan's essay Welcome Comrade! is a call to arms for hobbyist game programmers:

Propaganda poster Back in the day, it took a couple of man days to create a Doom level. Creating a Doom III level took multiple man-weeks. Thus budgets spiral every upward; as late as 1992, a typical computer game had a budget of $200,000. Today, 10 million dollars is your bare buy-in for a next generation title.

As budgets soar, publishers are increasingly conservative about what they will fund, because nobody wants to lose 10 million dollars. So they look for ways to reduce their risk. Today, they have become so risk-averse that anything other than a franchise title, a game based on a movie license, or a game that slots easily into a category they know how to sell is unthinkable.

Today, Myst, Civilization, or Sim City would never get funded.

We're condemned to more of the same-old same-old from now for all eternity--unless we figure out a way to break this iron grip--what Raph Koster calls "Moore's Wall."

We think it's possible-- by building for the game industry what the independent film and independent music movements do for their own industry. Creating a viable "independent games" movement, where people can experiment, at lower budgets and with less risk, on quirky, offbeat, innovative games-- and find an audience that prizes gameplay over glitz, innovation over graphical trickery, playfulness over polygons.

Greg's Manifesto Games website aims to make this a reality, by creating an audience and supporting hobbyist developers.

James Hague's Rise and Fall of the Hobbyist Game Programmer documents just how profoundly the world has changed for would-be game programmers in the last 30 years:

For a small percentage of enthusiasts, there's always been the calling to jump from just playing games to creating them. It's crazy, of course, because the rush of playing a great game doesn't carry over to spending twenty straight hours in the basement trying to figure out why a level initialization routine fails ten percent of the time. But those that persisted, they drove the industry in its early days.

I remember reading about Mark Turmell-- and others whose names I've forgotten-- who were somehow inspired to design their own games, and then sit down and figure out exactly how to turn them into something their friends could actually come over and play. Those were fantastic feats that started the chatter about computer games becoming a new art form. One person, one vision, and six months later a finished product that was snapped up by a publisher--pure creation. A new alternative for would-be novelists.

The dream is still alive in these days of 32-bit processors and 3D accelerators, but over the years the reality behind it has quietly slipped away and few have stopped to notice.

In 1981, personal computers were in the thick of their 8-bit heyday. Not only are we talking about an 8-bit 6502--a processor with one primary register and no multiply instruction--running at less than 2 megahertz, but it was still acceptable, though just barely, to write games in BASIC. Now don't get me wrong, BASIC was the downtrodden interpreted language that it still is, but it shipped with every Apple II and Atari 800, and was the obvious choice for budding programmers.

Perhaps this is another reason why the Visual Studio Express IDE should ship with Vista. Or maybe doing it as-is with the .NET 2.0 command-line compiler and Notepad is more authentic. For more perspective on how the game programming world has changed since those early days, I can highly recommend James Hague's essential 1997 e-book Halcyon Days: Interviews with Classic Computer and Video Game Programmers.

Perhaps it's a little easier to imagine transitioning from gamer to programmer in the world of mobile devices. Lightworks games is doing just that-- two guys pursuing their dream by building a game company from the ground up on the PocketPC. They started with Cavemen, a charming little Lemmings clone.

There's also Microsoft's intriguing XNA Game Studio, which is now available in beta. It's a way for hobbyist developers to write non-commercial games that run on the Xbox 360. There have been rumblings about the best of these non-commercial games eventually making their way to the Xbox Live marketplace-- which could potentially convert those hobbyist game programmers into small business owners. It's an exciting prospect, given the huge installed base of most consoles, and the ease of getting everything running on a standard console platform.

Is the dream of jumping from game player to game programmer still alive? It's certainly how I got my start in programming.

Discussion

Thread Priorities are Evil

Programmers* love to futz around with thread priorities. As if programming with threads wasn't already dangerous enough, we've got to get in there and tweak thread priorities to make things run.. er.. "better".

Setting process priority in Task Manager

Let's fire up Task Manager and take a quick survey of process priorities. Out of 38 processes running on my computer right now, I have 0 at low priority, 36 at normal priority, and 2 essential system processes (csrss and winlogon) running at high priority.

I bet almost every process on your machine is running at a base priority of "Normal", too. And there's a very good reason for this.

Witness K. Scott Allen's strange threading experiment:

This program behaves badly on a single processor machine, and pegs the CPU at 100% for over two minutes. On a multi processor machine, the program finishes all the threading work in the blink of an eye - only a brief CPU spike.

Strangely, if I remove a single line of code:

t.Priority = ThreadPriority.BelowNormal;

… then the program performs just as well on a single processor machine (only a brief spike - comparable to the multi processor scenario).

This little threading demo highlights one of the reasons a dual-core computer is so desirable -- it protects you from poorly written programs. If a program goes haywire and consumes 100% of CPU time, you still have a "spare" CPU waiting to pick up the slack. Whereas a single processor machine becomes totally unresponsive. That's why Task Manager itself runs at High priority-- so you can pre-empt these kind of runaway apps.**

Hardware fixes to software problems are never pretty. What's really going on here? Joe Duffy is something of an expert on the topic of threading and concurrency-- he works for Microsoft on CPU-based parallelism in the .NET Common Language Runtime-- and he has this to say:

Messing with [thread] priorities is actually a very dangerous practice, and this is only one illustration of what can go wrong. (Other illustrations are topics for another day.) In summary, plenty of people do it and so reusable libraries need to be somewhat resilient to it; otherwise, we get bugs from customers who have some valid scenario for swapping around priorities, and then we as library developers end up fixing them in service packs. It's less costly to write the right code in the first place.

Here's the problem. If somebody begins the work that will make 'cond' true on a lower priority thread (the producer), and then the timing of the program is such that the higher priority thread that issues this spinning (the consumer) gets scheduled, the consumer will starve the producer completely. This is a classic race. And even though there's an explicit Sleep in there, issuing it doesn't allow the producer to be scheduled because it's at a lower priority. The consumer will just spin forever and unless a free CPU opens up, the producer will never produce. Oops!

The moral of the story? [Thread] priorities are evil, don't mess with them.

Although there are some edge conditions where micromanaging thread priorities can make sense, it's generally a bad idea. Set up your threads at normal priority and let the operating system deal with scheduling them. No matter how brilliant a programmer you may be, I can practically guarantee you won't be able to outsmart the programmers who wrote the scheduler in your operating system.

* and users who think they're programmers
** assuming the runaway app itself isn't running at High priority, in which case you're in a world of hurt.

Discussion