There have been a lot of stories recently about a problem with Intel’s new Core Duo processors and USB 2.0 devices causing sharply decreased battery life. Mostly this has been a big Who Cares for me, but a Microsoft quote from AnandTech’s story on the problem caught my eye.
Windows XP SP2 installs a USB 2.0 driver that initializes any connected USB device. However, the USB 2.0 driver leaves the asynchronous scheduler component continuously running. This problem causes continuous instances of memory access that prevent the computer from entering the deeper Advanced Configuration and Power Interface (ACPI) processor idle sleep states.
I might be stretching a bit here, but this seems to be exactly the kind of problem that could have been anticipated on the basis of USB’s fundamentally broken design. Yes, that’s right, I said it’s broken. I use USB devices all the time, I don’t have any problem with them, but at a technical level I still consider it a broken protocol because it relies so heavily on polling. A little history might be in order here to explain how this happened and why it’s a problem.
A long time ago, Apple developed Firewire, which became standardized as IEEE 1394 and is also known by other names (such as Sony’s i.Link). Firewire was pretty fast for its time, at 400Mb/s in an era when 100Mb/s Ethernet was still considered pretty zippy, and it also had some special features to support devices such as video cameras. Later, Intel introduced USB, which was significantly slower (at 12Mb/s) than Firewire but also supposedly cheaper to implement. Intel spread a lot of FUD about the “Apple tax” of about $0.25 per port for licensing Firewire technology, never mentioning the fact that USB didn’t really come for free either; its cost was just buried a little deeper in the chipsets and motherboards that supported it. Firewire and USB could have coexisted quite easily, each being suited to different types of devices, but then Intel got even greedier and decided to go after the Firewire market with USB 2.0 at 480Mb/s. That’s nominally just a bit faster than Firewire, which is not at all a coincidence, but in reality test after test has shown that the very same device equipped with both interfaces will perform better using the supposedly-slower Firewire (note how the Firewire numbers are still better than even the higher PC-USB numbers). The reason for that will soon become clear.
While USB2 increased the raw bit rate significantly over its earlier sibling, it also carried along some USB1 baggage. In particular, it’s still based on a conceptual model of a PC at the center of the universe connected to dumb peripherals. The PC is the only one that can initiate anything; if an event occurs on a peripheral device (e.g. data becomes ready after a disk head travels to the right track) it still has to wait for the PC to come along and ask about it. Firewire, by contrast, is more “peer to peer” in nature. If a device has a message to send, it initiates the process of sending it. This typically results in an interrupt on the recipient, much the same way that networking cards work. This reliance on polling in USB vs. asynchronous messages and interrupts in Firewire might seem dry and uninteresting, but it does have important implications. It means that you can plug two Firewire devices (e.g. a video camera and a monitor) together and have them talk without needing a PC to mediate. You can sort of do this with USB On-The-Go but that’s just a hack to have two devices negotiate who’s on top; the fundamental protocol remains as it ever was, and Intel only added OTG as an afterthought when savvy Firewire users pointed out this shortcoming. The USB approach also has performance implications, explaining the apparent anomaly mentioned above. Polling simply consumes more resources, both “on the wire” and either on the device or on the PC (or both). I’m sure Intel thought it would be great to have the CPU do the polling, just like they think anything which wastes CPU time and forces people to buy faster processors is a great idea, but even they have been forced to implement most of the low-level polling elsewhere (typically in the south bridge). Obviously, though, some of the higher-level stuff such as device initialization still can’t be done that way, which is why Microsoft’s USB2 driver has to poll all the time … leading at last back to the problem we started with.
The key point here is that all of these problems – reduced convenience, reduced performance, reduced battery life – stem from the same fundamental mistake of designing an asymmetric protocol that relies on polling instead of symmetric asynchronous messaging to do its job. How many times will this mistake be repeated, more often nowadays in software rather than hardware, before people learn?