Coding Horror

programming and human factors

Changing Your Organization (for Peons)

James Shore's nineteen-week change diary is fascinating reading:

Warcraft Peon It was 2002. The .com bust was in full slump and work was hard to find. I had started my own small business as an independent consultant at the worst possible time: the end of 2000, right as the bubble popped. I had some noteworthy successes doing what I loved: coaching agile Extreme Programming (XP) teams in doing great work for a valuable purpose. And then the work dried up.

Eventually I admitted that I was going to have to find some "real" work to fill the gap. I took a contract job as a programmer on a team customizing some web software for a large institutional customer. This team was the opposite of agile. I was bored and frustrated. It didn't take me long to remember Martin Fowler's advice. As a peon, could I make the kinds of changes I made as a (damned good!) XP coach? Or would they kick me out, causing me to change organizations a little more abruptly?

James' story is an interesting one because he was attempting to effect organizational change with no formal power. He was, after all, merely a developer on the project. It's a bittersweet story of success and failure, but it does show that one developer can make a difference.

Discussion

Why Does Vista Use All My Memory?

Windows Vista has a radically different approach to memory management. Check out the "Physical Memory, Free" column in my Task Manager:

Task Manager Performance Tab in Windows Vista

At the time this screenshot was taken, this machine had a few instances of IE7 running, plus one remote desktop. I'm hardly doing anything at all, yet I only have 6 megabytes of free physical memory.

Now compare with this screenshot of Windows XP's Task Manager under similar low-load conditions:

Task Manager Performance tab in Windows XP

Under "Physical Memory, Available" I have approximately 1.5 gigabytes of free physical memory, as you'd expect.

So what's going on here? Why is Vista using so much memory when I'm doing so very little?

To answer that question, you have to consider what your computer's physical memory (RAM) is for. Just as a hypothetical, let's say you wanted to create a new text file:

  1. You double-click on the notepad icon.
  2. The Notepad executable loads from disk into memory.
  3. Notepad executes.
  4. Notepad allocates free memory to store your text document.

So Notepad clearly needs a little memory for itself: enough to execute, and to store the contents of the text document it's displaying. But that's maybe a couple megabytes, at most. If even that. What about the other 2,046 megabytes of system memory?

You have to stop thinking of system memory as a resource and start thinking of it as a a cache. Just like the level 1 and level 2 cache on your CPU, system memory is yet another type of high-speed cache that sits between your computer and the disk drive.

And the most important rule of cache design is that empty cache memory is wasted cache memory. Empty cache isn't doing you any good. It's expensive, high-speed memory sucking down power for zero benefit. The primary mission in the life of every cache is to populate itself as quickly as possible with the data that's most likely to be needed-- and to consistently deliver a high "hit rate" of needed data retrieved from the cache. Otherwise you're going straight to the hard drive, mister, and if you have to ask how much going to the hard drive will cost you in performance, you can't afford it.

Diomidis Spinellis published an excellent breakdown of the cache performance ratios in a typical PC circa January 2006:

Nominal Worst case Sustained Productivity
Component size latency throughput $1 buys (Bytes read / s / $)
(MB/s) Worst case Best case
L1 D cache 64 KB 1.4ns 19022 10.7 KB 7.91·1012 2.19·1014
L2 cache 512 KB 9.7ns 5519 12.8 KB 1.35·1012 7.61·1013
DDR RAM 256 MB 28.5ns 2541 9.48 MB 3.48·1014 2.65·1016
Hard drive 250 GB 25.6ms 67 2.91 GB 1.22·1011 2.17·1017

In summary, here's how much faster each cache memory type in your computer is than the hard drive:

System memory37x faster
CPU Level 2 cache82x faster
CPU Level 1 cache283x faster

Those figures explain why I only have 6 megabytes of "free" memory in Windows Vista. Vista is trying its darndest to pre-emptively populate every byte of system memory with what it thinks I might need next. It's running a low-priority background task that harvests previously accessed data from the disk and plops it into unused system memory. They even have a fancy marketing name for it-- SuperFetch:

In previous versions of Windows, system responsiveness could be uneven. You may have experienced sluggish behavior after booting your machine, after performing a fast user switch, or even after lunch. Although too many carbohydrates might slow you down after lunch, your computer slows down for different reasons. When you're not actively using your computer, background tasks -- including automatic backup and antivirus software scans -- take this opportunity to run when they will least disturb you. These background tasks can take space in system memory that your applications were using. After you start to use your PC again, it can take some time to reload your data into memory, slowing down performance.

SuperFetch understands which applications you use most, and preloads these applications into memory, so your system is more responsive. SuperFetch uses an intelligent prioritization scheme that understands which applications you use most often, and can even differentiate which applications you are likely to use at different times (for example, on the weekend versus during the week), so that your computer is ready to do what you want it to do. Windows Vista can also prioritize your applications over background tasks, so that when you return to your machine after leaving it idle, it's still responsive.

This isn't a new concept, of course. But Vista treats system memory like a cache much more aggressively and effectively than any other version of Windows. As alluded to in the above lunch anecdote-- and as you can see from the Task Manager screenshot above-- Windows XP has no qualms whatsoever about leaving upwards of a gigabyte of system memory empty. From a caching perspective, this is unfathomable. Vista tries its damndest to fill that empty system memory cache as soon as it can.

Although I am a total believer in the system-memory-as-cache religion, SuperFetch can still have some undesirable side effects. I first noticed that something was up when I fired up Battlefield 2 under Vista and joined a multiplayer game. Battlefield 2 is something of a memory hog; the game regularly uses a gigabyte of memory on large 64-player multiplayer maps. During the first few minutes of gameplay, I noticed that the system was a little sluggish, and the drive was running constantly. This was very unusual and totally unlike the behavior under Windows XP. Once the map is loaded and you join the game, the entire game is in memory. What could possibly be loading from disk at that point? Well, SuperFetch saw a ton of memory freed to make room for the game, and dutifully went about filling the leftover free memory on a low-priority background disk thread. Normally, this would be no big deal, but even a low-priority background disk thread is pretty noticeable when you're playing a twitch shooter online with 63 other people at a resolution of 1600x1200.

I'm perfectly fine letting SuperFetch have its way with my system memory. The question shouldn't be "Why does Vista use all my memory?", but "Why the heck did previous versions of Windows use my memory so ineffectively?" I don't know. Maybe the rules were different before 2 gigabytes was a mainstream memory configuration.

The less free memory I have, the better; every byte of memory should be actively working on my behalf at all times. However, I do wish there was a way to tell SuperFetch to ixnay on the oadinglay when I'm gaming.

Discussion

Company of Heroes

My latest gaming obsession is the new real-time strategy game, Company of Heroes. It's easily one of the best games of the year for the PC. And it's quite possibly one of the best real-time strategy games ever made. To give you an idea of what I'm talking about, the game currently has a 95% review average on GameRankings with 13 reviews, which puts it squarely on track to be one of the top 10 best reviewed PC games of all time.

It's so good, in fact, that I was compelled to complete every optional objective in the campaign missions.

Company of Heroes screenshot

The Company of Heroes demo is a whopping 1.8 gigabytes in size, but it offers a significant chunk of the game: unlimited, unlocked skirmish mode against the CPU and two single player maps.

Sure, the World War II genre has been done to death. But this is a real-time strategy game with incredible graphical detail, dynamic, destructible levels, and unparalleled unit intelligence and tactics. It elevates the entire real-time strategy genre to the next level.

Company of Heroes is the first new game I installed after installing Vista RC1. Coincidentally, it's also one of the first games with Microsoft's "Games for Windows" certification, which means (among other things) that it integrates automatically into Vista's Games menu.

Needless to say, highly recommended. If you've ever played and enjoyed an RTS game of any type, buy this game immediately. For everyone else, get the demo and try it yourself. I think you'll be impressed.

Discussion

Fifty Years of Software Development

O'Reilly's History of Programming Languages poster is fascinating reading.

Detail from O'Reilly History of Programming Languages poster

If you trace programming languages back to their origins, you'll find that we've been at this programming stuff a long, long time.

C is roughly as old as I am; FORTRAN is as old as my parents. But what about the new kids on the block? the TIOBE software TCPI metrics page provides some data on language popularity going back to the year 2001. Consider the tender age of many of the newest, hippest programming languages:

Ruby is barely a teenager. JavaScript hasn't even hit its teens yet.

Now correlate the ages of those modern languages with the publication dates of a few books that represent current thinking in modern software development:

1994Object-Oriented Design (Booch)
1995Design Patterns (GoF)
1997UML Distilled (Fowler)
1999Extreme Programming Explained (Beck)
1999Refactoring (Fowler)
2001Agile Alliance is formed

Modern software development is a recent development. Even though we collectively have over fifty years of experience under our belt, the profession of software development is still very much in its infancy.

Consider source control as an example. Source control is the absolute bedrock of software engineering. I believe that source control was not widely prevalent until 1999. Here's why:

  1. Although CVS has been around since the late eighties, it was widely popularized through SourceForge, which didn't exist until the year 2000.
  2. Microsoft's SourceSafe was available starting in the mid-90's but didn't hit mainstream acceptance until it was bundled as a part of Visual Studio 6.0 Enterprise in 1998.

Clearly, source control existed before the year 1999. Why did it take so long for this essential tool of software engineering to filter down to the mainstream? The answer lies in the Redwine-Riddle maturation model (pdf):

Redwine and Riddle reviewed a number of software technologies to see how they develop and propagate. They found that it typically takes 15-20 years for a technology to evolve from concept formulation to the point where it's ready for popularization.

They identify six typical phases:

  • Basic research. Investigate basic ideas and concepts, put initial structure on the problem, frame critical research questions.
  • Concept formulation. Circulate ideas informally, develop a research community, converge on a compatible set of ideas, publish solutions to specific subproblems.
  • Development and extension. Make preliminary use of the technology, clarify underlying ideas, generalize the approach.
  • Internal enhancement and exploration. Extend approach to another domain, use technology for real problems, stabilize technology, develop training materials, show value in results.
  • External enhancement and exploration. Similar to internal, but involving a broader community of people who weren't developers, show substantial evidence of value and applicability.
  • Popularization. Develop production-quality, supported versions of the technology, commercialize and market technology, expand user community.
Redwine and Riddle presented timelines for several software technologies as they progressed through these phases up until the mid-1980s. I presented a similar analysis for the maturation of software architecture in the 1990s.

CVS was released in 1986. It took another fifteen years for CVS usage to become mainstream, exactly as predicted by Redwine-Riddle.

The model Redwine-Riddle proposed in 1980 is very much alive today. Mark Dominus, in Design Patterns of 1972, reaches back nearly thirty-five years to illustrate how we're still struggling to evolve our programming languages today:

Had the "Design Patterns" movement been popular in 1960, its goal would have been to train programmers to recognize situations in which the "subroutine" pattern was applicable, and to implement it habitually when necessary. While this would have been a great improvement over not using subroutines at all, it would have been vastly inferior to what really happened, which was that the "subroutine" pattern was codified and embedded into subsequent languages. Identification of patterns is an important driver of progress in programming languages. As in all programming, the idea is to notice when the same solution is appearing repeatedly in different contexts and to understand the commonalities. This is admirable and valuable. The problem with the "Design Patterns" movement is the use to which the patterns are put afterward: programmers are trained to identify and apply the patterns when possible. Instead, the patterns should be used as signposts to the failures of the programming language. As in all programming, the identification of commonalities should be followed by an abstraction step in which the common parts are merged into a single solution.

Multiple implementations of the same idea are almost always a mistake in programming. The correct place to implement a common solution to a recurring design problem is in the programming language, if that is possible.

The stance of the "Design Patterns" movement seems to be that it is somehow inevitable that programmers will need to implement Visitors, Abstract Factories, Decorators, and Faades. But these are no more inevitable than the need to implement Subroutine Calls or Object-Oriented Classes in the source language. These patterns should be seen as defects or missing features in Java and C++. The best response to identification of these patterns is to ask what defects in those languages cause the patterns to be necessary, and how the languages might provide better support for solving these kinds of problems.

I do think the pace of change in software development is quickening, thanks to exponential increases in communication over the last fifty years-- television, satellites, cellular phones, and of course the internet. As software developers, we've grown accustomed to computer hardware doubling in speed every 18 months. What we haven't been able to cope with so well is how long it takes for the human beings to catch up with the hardware.

Discussion

How big is your Lap, Anyway?

Laptop magazine's Attack of the 20-inch Notebook is a tongue-in-cheek look at using the Dell XPS M2010 as a portable system in a few different locations.

The Dell XPS M2010 in action

Hilarity ensued. For context, here are the relevant specs of this semi-portable concept system:

  • 20" LCD
  • full-size bluetooth keyboard (with numeric pad)
  • 16.75" h x 19.25" w x 3" d
  • 20.3 pounds with AC adapter

Shades of the original 28 pound Compaq Portable, although the 9" text-mode monochrome monitor and 4.77MHz 8088 aren't nearly as impressive.

Although the XPS M2010 is an extreme case, I never quite understood the fascination of those giant 10+ pound desktop replacement laptops. You can even buy batteryless laptops that must be plugged in -- so-called "Mobile PCs". Isn't portability the whole point of a notebook computer?

I adored my three pound Dell Inspiron 300; travelling with it was effortless. I compromised a bit for maximum Vista performance with my 5.5 pound Asus W3J, which is a great machine, but at nearly double the weight it's also a more noticeable burden. That's absolutely as large as I'm willing to go for a laptop. I'd much rather be using an ultraportable like the 2.2 pound Samsung Q2010 or the 3 pound Dell D420.

Discussion