News: 2007 -

Sawdust and lies

12/31/2007 - Version 3.4 of my MinGW Distro updates SDL to 1.2.13.

12/29/2007 - Version 3.3 of my MinGW Distro contains a fix for a nasty Boost.Function bug.

12/11/2007 - Mass Effect is incredible. Absolutely incredible. The only game that I can possibly compare it to is Deus Ex, and I find it hard to decide which one is better. (It doesn't help that they're separated by so many years.) Everything that I love about Deus Ex is either replicated by or counterbalanced with something in Mass Effect (aside from multiplayer). An original science fiction story of stunning depth, check. Excellent music (with a soundtrack CD, like all games should have), check. Hybrid RPG/shooter, check. Awesome gameplay moments (escaping from MJ12 into UNATCO, understanding the meaning of the Relay Monument), check. DX has in-game documents (books, E-mails), while ME has Codex entries explaining the game universe as if from an encyclopedia. DX's marvelous conversation system has finally been superseded by ME's wheel-based conversation system (which should serve as the basis for all future games), although only DX has great bartender conversations. DX has minute-to-minute nonlinearity, while ME has Paragon and Renegade paths (which are infinitely better done than Jade Empire's Way Of The Open Palm and Way Of The Closed Fist; Knights Of The Old Republic's Light and Dark Sides aren't really comparable, since it has to be true to Star Wars). Basically, DX made me feel like I really was living in a nanotech-powered future, while ME made me feel like I was helping humanity's entrance into galactic affairs.

The rest of my time has gone into constructing Demerzel. I carefully plan things so that I don't have to deal with them going wrong, but as ever, things went wrong. It turned out that my case, motherboard, and heatsink were incompatible; the motherboard placed the CPU socket very close to the edge, the case placed a metal divider very close to that edge, and the heatsink I had so carefully selected would not fit in any of the four possible orientations. I had to order a Thermalright Ultra-120 Extreme, which does fit (although I think that I won't be able to upgrade the RAM without taking the entire motherboard out and removing the heatsink; I'll deal with that if and when 4 GB isn't enough and I need to max it out to 8 GB).

As usual, building a new computer (Demerzel is the third computer that I've built from scratch) was epic. I bought a cheap Celeron to flash the motherboard BIOS with; my Northwood and Prescott processors worked with their motherboards from the start, but I had heard reports that my motherboard wouldn't work with Yorkfield processors without flashing the BIOS. I went through the expense and hassle of the Celeron in order to avoid discovering whether those reports were correct or not. Fortunately, I didn't nick any motherboard traces, or shock anything with static electricity, while I was working with the parts. After the unwelcome heatsink discovery, the only other problem that I had was with flashing my Serial Attached SCSI RAID card's BIOS. As I expected, the motherboard's BIOS flashed just fine from a USB flash stick, and Vista can load storage drivers from a CD. These were very welcome advances; Reason's motherboard had to be flashed from a floppy drive, and XP needed a floppy drive to load storage drivers. I was planning on getting away without ever connecting a floppy drive to Demerzel, when I discovered that the SAS RAID card could be flashed from only floppies. (There's an Adaptec Storage Manager utility program that runs in Windows; however, it apparently cannot flash a card that was used to boot the system.) Then I discovered that my half-decade-old floppy disks could no longer be reliably formatted; I hate floppies so much. I had to buy new floppy disks (and while I was at it, a new floppy drive); the humiliation was more painful than the cost.

Demerzel's hardware is now fully set up, and I've installed Vista 64. Now I just have to configure it to my liking, install lots of programs, and transfer my files over from Reason. This will probably take me a month (if I'm fast; fortunately, I've got two weeks of winter vacation in which to set up Demerzel), but at least the hard part where I touch thousands of dollars of electronic equipment with my bare hands is over.

Just as I planned, Demerzel is insanely quiet; this is a big change from Reason (which is much louder than any desktop computer sold by any retailer) and Northy (which is now unbearably loud to me; of course, it never suffered the heat problems that Reason suffers). It's also relatively cool; loading up all four cores with Prime95, the hottest cores reached about 55 degrees Celsius. Unfortunately, there was roughly a 10 degree gap between the hottest and coolest cores; stupid Ultra-120 Extreme mounting system. Anyways, I'll live.

I also bought a cell phone. (Actually, I did this about two months ago, but I've been busy and haven't had a chance to write about it until now.) After switching from Verizon DSL (with its insanely slow download and criminally slow upload) to Comcast cable (with reasonably fast download and merely obnoxiously slow upload), I've now freed myself from Verizon entirely. I no longer have a landline, thanks to FCC-mandated number portability. (Yay, federal government regulations!) T-Mobile Prepaid is my liberator; even if I spend $200/year on 2000 minutes, I'm saving a bundle of money compared to the $600+/year I was spending on Verizon. I truly am my father's son; once I figured out that a cell phone would be cheaper than a landline instead of more expensive, Verizon became intolerable to me. (Well, we aren't exactly the same; without number portability, I would have stuck with Verizon a lot longer, whereas my father is infinitely more disciplined in the pursuit of not spending money.) The other benefits, like being able to make a phone call from anywhere and having a contact list in my phone, are just icing on the cake. It also happens that my apartment is a Faraday cage and I usually get about one bar of reception, but that's not the end of the world.

After being exhorted to do so by a couple of readers, I've read Sundiver, Startide Rising, and The Uplift War, the first three novels in David Brin's Uplift series. Sundiver wasn't very good, but it so happens that I have a very high tolerance for bad SF (after all, I finished Neal Stephenson's Quicksilver - the ginormous hardcover and not the identically-named first of the paperbacks that it was split into - although I wonder if I'll have the stomach to reread it in order to review it). Startide Rising was reasonably good, and The Uplift War was even better, so I'll read more books from the series.

Speaking of my various projects, why don't I review SF novels as I read them, instead of letting them pile up? There are a couple of reasons. One, I prefer to read novels for enjoyment the first time; it's rather distracting to think about how interesting a novel is. Two, I don't trust my initial reactions to be stable, especially if the novel is very unfamiliar. I managed to sleep through The Fellowship Of The Ring the first time that I read it (of course, that was at Caltech, when I slept through everything). I also, unbelievably, didn't get Vinge's "Fast Times At Fairmont High" the first time that I read it. Somehow, on my second read, I realized that it was awesome.

After I get myself switched over to Demerzel and do some more work on Spacetimewar, I think I'll start reviewing "a book a week". At that pace it'll take four years to get through my SF backlog, but it's better than "zero books a week".

And speaking of Spacetimewar, I figured out how to achieve perfect dependency generation with GNU Make and MSVC. As usual, this involves more trickery than with GCC, but it's not too hard. As soon as I get a chance, I'll write a page about it. Spacetimewar's build system uses perfect dependency generation, which is one of the reasons I can't wait to build it with Demerzel's quad-core Yorkfield.

In gaming-related news, I've played Carcassonne and Tigris And Euphrates, both of which were excellent, and I've picked up the new deck of Power Grid plants, which looks like an extremely well-thought-out improvement to the original game. Oh yeah - and after I finished Mass Effect, my Xbox 360 died. Again.

For the curious, here's Demerzel's spec:

CASE: Lian Li PC-V1100BplusII                   - $249.99
MOBO: Gigabyte GA-X38T-DQ6                      - $299.99
PROC: QX9650 (Yorkfield-3.0)                    - $1195
STARTER PROC: Celeron 420                       - $43.99
RAM: 4x OCZ 1GB CL7 DDR3-1333                   - $799.98
VIDEO: EVGA 8800 Ultra 768MB 612/2160MHz Retail - $629.99
SAS RAID-1 PCI-E x4: Adaptec 3405               - $304.99
PSU: Enermax Galaxy DXX 1000 (EGX1000EWL)       - $329.99
BURNER: Lite-On Black SATA LH-20A1L-06 Retail   - $37.99
ROM: 2x ASUS Black SATA DVD-ROM DVD-E616A3T OEM - $37.98
FANS: 4x Scythe SFF21F 120mm                    - $51.96
SHIPPING:                                       - $13.21

SAS HD: 2x Seagate Cheetah 15k.5 300 GB SAS     - $1296.90
SAS CABLE: Adaptec 2231900-R 0.5-meter          - $33.15
SHIPPING:                                         $54.84

HS: Thermalright Ultra-120 Extreme              - $58.95
SHIPPING:                                       - $27.60

USB: Quad USB 2.0 Bracket                       - $12.50
SHIPPING:                                       - $11.56

GRILLES: 4x 120mm                               - Already have
SATA CABLES:                                    - Included with mobo
SOUND:                                          - Integrated on mobo

Total: $5490.56

This glosses over a few facts, like how I temporarily needed a floppy drive, and how I used the Arctic Silver 5 that came with the Enzotech Ultra-X instead of the no-name paste that came with the Thermalright Ultra-120 Extreme. Also, I used only two ports of the quad USB 2.0 bracket, routing the other two to the front panel. (Reason has four native USB 2.0 ports and a dual bracket; I recently noticed that it has headers for two more ports, which would have come in handy. Demerzel has eight native USB 2.0 ports, and headers for four more. Yum!) I ordered fast shipping for the hard drives and heatsink.

Finally, I have removed the Computer page, as it was seriously stale and it was never useful to begin with. I originally wanted to create cool pages; now I understand that the best pages are useful.

11/19/2007 - I have revised the MinGW Distro page, moving most of the bulky version history to the bottom. My pages tend to be heavyweight, filled with text and wanting to be thoroughly read instead of quickly skimmed, but over the years I've gotten better at arranging things so that the most important stuff is at the top.

Aside from playing an unhealthy amount of Call Of Duty 4: Modern Warfare, I've finally ordered my new computer, Demerzel! Some of its components, like the Serial Attached SCSI hard drives that I'm so fond of, have already arrived, with the rest arriving tomorrow. Demerzel won't just be a way for me to sink ridiculous amounts of time into Supreme Commander: Forged Alliance; it'll also allow me to do multicore builds of libnuwen and Spacetimewar. Also, Spacetimewar's engine will be dual-threaded, so Demerzel's quad-core Yorkfield will be a lot better for development than Reason's single-core (with HyperThreading) Prescott.

10/27/2007 - Miscellaneous updates today! I added three links to the Links page, added a scan of Fleet Of Worlds to the SF Reviews page, and updated my age and job title (finally!) on my personal page. Also, as promised, I have removed the GeForce FX page; the 5800 Ultra is now three major generations behind the state of the art.

Recently I've spent a lot of time playing BioShock, Halo 3, and Puzzle Quest (and at work, drinking free Game Fuel). Naturally, this has cut into my time for doing other things, but at least it's not like when I lost a year (or what felt like a year) to World Of Warcraft. Hopefully, Mass Effect won't devour my life for too long.

I also spent a vanishingly small amount of time playing the demo of Battlestar Galactica on Xbox Live Arcade. It's so bad, Spacetimewar should be better than it almost by default. Now, I just need to work on Spacetimewar....

10/22/2007 - Version 3.2 of my MinGW Distro updates libpng to 1.2.22.

10/10/2007 - Being a programmer, I see a lot of bugs every day. I produce bugtrocity myself from time to time. Some bugs are subtle, and some are glaring thinkos wearing jingle bells. You'd think well-tested code would be mostly free of the latter category... wouldn't you?

I recently invested in five mutual funds directly. Wanting to analyze their performance, I wrote a C++ program to calculate annual percentage yields for each fund and my entire portfolio. (Fidelity tells me the year-to-date growth of my 401(k), but they don't seem to report that for ordinary investments, and nowhere do I see overall growth displayed as an APY. The APY matters to me because one look at it will tell me whether my funds are outperforming my CDs or not.) Naturally, my program worked; I had committed a normal number of thinkos, but they were all compile-time except for one that was instantly detected at run-time (I gave one argument to boost::format when I should have given two; it threw an exception instead of mangling things horribly).

To verify my program's results, I calculated APYs for my funds by hand. (Only one day had elapsed since I bought the funds.) My program was producing correct results, rounded up to the next basis point - a victory for modern C++. But then I noticed something very interesting about Google Finance: it was buggy. Here's a screenshot:

JAOSX At Google

JAOSX had increased in value from $59.89 to $60.91. Google Finance reported this $1.02 increase as an increase of 1.67%.

That's wrong. 1.02 is indeed 1.6746% of 60.91, but percentage movements have to be reported in terms of the old value, not the new value. (If something was $10 yesterday and it is $15 today, it has increased in price by 50%, not 33.33%.) The correct answer is that 1.02 is 1.7031% of 59.89. One would hope that Fidelity gets it right, and they do:

JAOSX At Fidelity

Yahoo Finance also gets it right:

JAOSX At Yahoo

Live Search does the calculation correctly, but rounds up:

JAOSX At Live Search

Rounding up to the next basis point is kind of silly, but it might be defensible (it would report extremely small movements as 0.01% instead of 0.00%). (My C++ program rounded up to the next basis point because of how I did my calculations - not seeing an obvious way to calculate an APY given multiple purchases over a period of time, I simply tested each APY starting from -100% (i.e. "I've lost everything") going up by increments of 0.01% and stopped when the hypothetical APY resulted in more growth than actually happened. In contrast, one-day percentage movements can be calculated directly with high precision.)

Rounding cannot explain Google Finance's erroneous percentage display. For shame!

10/8/2007 - I added several new links to the Links page. I also fixed links that had become stale.

I added scans of The Algebraist and Halting State to the SF Reviews page.

("Boring!", you say. "Why don't you review some SF novels, or work on Spacetimewar?" Well, I need to do boring maintenance, or I'll accumulate a horrific amount of deferred work (stale links, unscanned books). And huge backlogs make me feel terrible.)

I'll probably nuke the GeForce FX page soon (as I nuked the GeForce 3 page before it). I'm getting much better at writing pages that withstand the test of time, but I've still got a bunch of old pages to deal with.

9/23/2007 - I completely revised my Rating System, simplifying it considerably. I also created new star images, which are sharper and brighter than my old star images. Here's a comparison, with the new stars on the left:

New Versus Old Stars
New Versus Old Stars

As the colors indicate, the new five star rating is equivalent to the old eight star rating, the new four to the old seven, and the new three to the old six. The new two star rating is equivalent to the old five star rating (I never liked the blue and yellow colors). The new one star rating is equivalent to the old two, three, and four star ratings.

My new rating system should be easier to understand; it should also be easier for me to use. My old rating system had so many ratings (2, 3, 4, 5-, 5, 5+, 6-, 6, 6+, 7-, 7, 7+, 8) that I had to think really hard about exactly how much I liked something before choosing a rating. Eventually I realized that a lot of the information conveyed by my old rating system was useless, like all quality-based rating systems. The new action-based rating system conveys just the important information.

I updated the SF Reviews to use the new ratings. The Anime/SF Reviews still use the old ratings, and the Book Reviews still use the ancient ratings.

I updated the Image Hacking page with an explanation of how I created the star images, as well as high-resolution versions.

Separately, I updated the Links page, removing Windows XP and Nuvola icons that I had semi-arbitrarily chosen to represent links. The only icons remaining are "real". This removes visual noise, and should make it easier for me to add new links. (Choosing new icons was always an ordeal.)

9/17/2007 - I added a scan of The Accidental Time Machine by Joe Haldeman to the SF Reviews page.

9/10/2007 - Version 3.1 of my MinGW Distro adds GLee 5.21.

8/26/2007 - It seems like a good time to reveal the identity of my Project Which Must Not Be Named!

Spacetimewar Renderer
Spacetimewar Renderer

I call it Spacetimewar, and it is a game. Or will be - the screenshot above demonstrates various capabilities of the renderer, as well as the input and music systems. Soon, I will write a game loop, and then it'll actually resemble a game.

I forget exactly when I started working on Spacetimewar; my old news posts indicate that it was in June 2006. As the name implies (hopefully), it will be a 2D real-time space game. I don't think the "fly around in a ship and blast stuff" genre has been fully explored yet. I plan for it to center around online multiplayer, with an offline tutorial.

In addition to working on the Spacetimewar code itself, I've built it on top of libnuwen. The most obvious indication of this is the JPEG loading code that I added to libnuwen. (I have similar PNG loading code in Spacetimewar, but I haven't lifted it out yet.) And I've trawled the Internet for resources, which has been surprisingly rewarding. I've already found excellent music available under the Creative Commons Attribution license, as well as free fonts and backgrounds. At this point, the only unknowns in terms of resources are art (which I can fake, at least at first, with polygons) and sound (which I've found a promising website for). The only significant coding challenge that I anticipate is networking. Armed with my continually advancing knowledge of C++, the tasks of rendering, input, and even music have easily been conquered. Only Shub-Internet, with its slavering latency and razor-sharp APIs, stands in my way.

This is quite a difference from my first C++ game, Parrises Squares, in which I struggled with the simplest of rendering and input tasks. As I've worked on Spacetimewar, the solutions to mysteries of Parrises Squares have been revealed. For example, Parrises Squares struggled to maintain a decent framerate, even though it was just drawing a 1600x1200 background texture and a bunch of 48x48 sprites. Now I know that because I wasn't using texture objects, my textures were being sent over AGP to the video card every frame. Also, I never understood its unreasonable memory usage (something like 100 MB) until I implemented music in Spacetimewar. When I wrote Parrises Squares, I didn't know how to do music. Eventually I just used a simple Windows API function. That function was decompressing my music into main memory and keeping it there, instead of streaming it from the disk. D'oh!

I haven't had a lot of time recently to play games, even though some really good ones are out. I haven't gotten Bioshock yet (for shame!), and Neverwinter Nights 2 is still sitting half-played on my hard drive. And I'm even less likely to finish Oblivion. With Halo 3 coming out in a month (which I will definitely be playing), I don't know how I'll survive. I did get Hexic 2 as soon as it came out, and it's better than the original. Hexic HD's gameplay was rather simple (although not as simple as Bejeweled 2); Hexic 2's gameplay is deeper. It does, however, contain an amusing bug. Saving and loading a Marathon game can cause bombs to permanently cease falling. As bombs are the only things preventing you from playing the game forever (especially now that you can detonate black pearls in order to avoid winning the game), this is rather obnoxious. The only possible explanation for this bug that I can imagine is stone cold incompetence in development and testing.

I also bought the two Power Grid expansion boards, although I haven't used them yet. I've branched out from board games and have begun playing card games with my friends. Gloom (which my sister was ranting about) and Hex Hex (which I picked up on a whim because its box was cool) turned out to be incredibly fun.

Finally, I watched The Last Mimzy through the Xbox Live Video Marketplace (ugh, what a mouthful) because the Flick Filosopher said it was awesome. She was right: I haven't enjoyed a PG-rated movie that much since The Incredibles. The Last Mimzy actually reminds me a lot of Explorers, one of the movies that I watched while growing up, except with a significantly better plot and modern special effects (the depiction of the crystal/paperweight's power is really neat). And The Last Mimzy has an ending that doesn't suck.

8/19/2007 - Version 3.0 of my MinGW Distro updates GCC to 4.2.1-dw2-2. This generates significantly more efficient code, and contains the mingw-local patches that I had previously abandoned. Also, I have added bzip2/zlib support to Boost.Iostreams. Finally, grep has been updated with much fancier coloring.

bzip2/zlib support has also been added to Boost.Iostreams in the VC8 SP1 library pack. Although libnuwen does not require this, I always keep the library pack in sync with the distro.

When using this new stuff with GCC, you must link with -lboost_iostreams -lbzip2 or -lboost_iostreams -lz . With VC8 SP1, no linker incantations are necessary; special directives in the Boost headers will automatically drag in the separately compiled libraries that are required.

8/2/2007 - Version 2.8 of my MinGW Distro adds DirectX support to SDL.

7/25/2007 - My server's hard drive failed yesterday afternoon, knocking offline. Rackspace worked overnight to install a new hard drive and restore everything from their automated weekly backups (fortunately, a weekly backup completed just before the old hard drive failed). The contents of itself were never in any danger as it was covered by the weekly backups, and it is inherently a mirror of the copy on my local hard drive (which is a RAID-1 array). Some other data, which I had intentionally excluded from the weekly backups, had to be salvaged from the old hard drive. (My server hosts random files for myself, as well as websites for some of my friends.) I'm currently working on that.

Version 2.7 of my MinGW Distro updates Boost to 1.34.1. I also figured out how to build libogg, libvorbis, vorbis-tools, and SDL_mixer. (Can you guess what my Project Which Must Not Be Named is?)

7/20/2007 - Version 2.6 of my MinGW Distro is now available. I figured out how to build SDL in a better way, making the static and dynamic libraries much smaller.

7/9/2007 - In the pursuit of increased readability, the Contents of my MinGW Distro are now presented in a table.

For a long time, I have redirected requests for pages with .shtml and .htm extensions to use the proper .html extension. Now, I also redirect to . (I previously used a RedirectMatch directive from Apache's mod_alias; I now use superior mod_rewrite machinery.) If activated, these redirections will cause the URL entered into the address bar of your browser to change. My platinum-iridium fist (of benevolence!) is inescapable.

7/4/2007 - I reorganized the site directory some more.

7/1/2007 - I slightly rearranged the site directory.

What have I been doing recently? Let's see... aside from rewatching anime like Trigun and Vandread, I've gotten into reading comic books. I've always liked media derived from comic books (movies, games, cartoons), but I never actually read the original sources. I got V For Vendetta, written by Alan Moore, back in April 2006 after seeing the movie. It wasn't until September 2006 that I heard about Marvel Zombies, written by Robert Kirkman, which had a concept that was too cool to pass up. I found it so entertaining that the next month I bought Kirkman's series The Walking Dead, which is like a zombie movie that keeps going on and on. And in May 2007 I got Kirkman's other series Invincible, which is like a superhero movie that keeps going on and on. (I'm actually kind of surprised, looking at my Amazon history - usually I'm a little faster at depth-first-searching authors that I like. I guess Invincible sounded kind of weird to me at first, and I'm very reluctant to try new things. Silly me - it turned out to be awesome.) Both The Walking Dead and Invincible are still being published with no end in sight, which makes me very happy.

I underwent a life-changing event in May. There are basically three places where I spend time in my apartment: reading books in bed, sitting on my couch playing Xbox 360 or watching DVDs on my HDTV (it's not hooked up to either network or cable television), or sitting at my computer. (I don't read on the couch as I have only one 100W light in the HDTV room, while my bed is right next to 280W of light.) And the majority of my time is spent at the computer. For almost three years, I used a metal folding chair in front of the computer. In May, my parents drove over from Colorado to attend my sister's graduation in Oregon; afterwards, they took me to Costco and I got a real computer chair for the first time. It's even better than the one I have at work! I don't know how I tolerated living in misery for so long. (Well, buying anything large is woefully inconvenient for me, as I don't have a car. That's why it took me so long to replace my metal folding chairs with the couch and then the computer chair.)

I've also been spending a lot of time planning how I'm going to build my next computer, Demerzel. Whenever I build a new computer, I have to catch up on the latest technology and figure out how to choose parts that are going to work when I put them all together. For example, it took an incredible amount of time for me to figure out how Serial Attached SCSI cables work; I had no idea what to get until I found an Adaptec guide to SAS cables. (It turns out that a special fanout cable is used, where one controller connector splits into four drive connectors, each of which also take Molex power.) And then I had to figure out where to buy SAS cables and drives, which was another ordeal.

One of my biggest headaches has been choosing Demerzel's heatsink. When I build a new computer, I always choose the most powerful processor available. Northy's Northwood-2.2 dissipated 57W and was very well cooled by a Swiftech MCX-478 and a powerful 80mm fan. Reason's Prescott-3.2, however, dissipates 103W. Even with a Swiftech MCX-4000 and a powerful 92mm fan, it reaches about 70 degrees Celsius under maximum stress. (I discovered this while playing Supreme Commander, when Reason would start to beep while playing long games. After removing the dust-clogged filter from my top 120mm intake, my maximum processor temperature dropped to about 68 degrees Celsius - just below the warning zone.) The good news for Demerzel is that heatsink technology has significantly advanced since I built Reason. Heatsinks now use heatpipes, making my MCX-4000 (a huge chunk of copper with aluminum pins stuck on top) look positively paleolithic. And now, heatsinks finally use 120mm fans, which move more air than 92mm fans. The bad news is that I want Demerzel to be significantly quieter than Reason, which means no more fan insanity. Also, while Intel has improved their performance-per-watt with their Core architecture and 65nm process (and upcoming 45nm process) compared to the NetBurst architecture and 90nm process, that hasn't reduced processor wattage. At the high end, all of these gains have been put into increased performance instead of decreased energy consumption. The QX6800 (Kentsfield-2.93) has a Thermal Design Power of 130W. So, my choice of heatsink is more critical now than ever.

After looking at basically every high-end Socket 775 heatsink available, I chose the EnzoTech Ultra-X. It has four 8mm diameter heatpipes (instead of the more common 6mm) and a down-blowing 120mm fan. Most reviews on the Internet agree that down-blowing heatsinks are somewhat less effective than side-blowing heatsinks, although they're still quite good. (My guess is that this is not caused by down-blowing fans resulting in poorer air circulation, as the air inside a case is going to be pretty well mixed with several 120mm fans circulating air. Nor do I think that this is caused by down-blowing fans experiencing more back-pressure, since the fans are positioned rather far away from the motherboard. I think it's because each heatpipe in a down-blowing heatsink has one end going into the fins, while each heatpipe in a side-blowing heatsink has two ends going into the fins.)

Why has choosing a heatsink been such a headache? Why did I choose the Ultra-X instead of the side-blowing heatsink widely regarded as the most efficient, the Thermalright Ultra-120 Extreme? One simple reason: the mounting mechanism. Basically every high-end Socket 775 heatsink (except for the Ultra-X) has a brain-dead mounting mechanism. This drives me nuts, because mounting the heatsink to the motherboard is one of the hardest parts of building a computer (the other hard part is mounting the motherboard to the case - both are difficult because you have to work with screws in tight spaces). And with today's extremely heavy heatsinks, poor mounting can cause the heatsink to not make complete contact with the processor. It's the secret downside to tower cases.

Here's my three-point test for heatsink mounting mechanisms. First, the heatsink must have a bolt-through-board-to-backplate system. That's the second most secure system possible (only bolt-through-board-to-chassis, like workstations use, is better - but Socket 771 has lousy heatsinks anyways). The thought of a nearly 2-pound heatsink secured by push-pins makes me queasy. (My Swiftechs used bolt-through-board as they predated the introduction of backplates. As a result, although they are securely mounted, they exert a bending force on the motherboard.) Second, spring-loaded screws must be used between the heatsink and backplate. Only springs can ensure that a predictable amount of force is used to hold the heatsink to the processor. Third, the heatsink must be secured by at least three (usually four) points. Heatsinks which are held down by two points can rock in one direction, potentially allowing them to tip off of the processor. Being held down by one point is even worse - not only might the heatsink make uneven contact with the processor, but it can also rotate! "But wait," you say, "what kind of heatsink would use such an incompetent mounting mechanism?" Why, the Thermalright Ultra-120 Extreme. Although it uses four spring screws which bolt-through-board-to-backplate, what is bolted to the motherboard is a collapsible bracket. The bracket holds down the heatsink itself by a single point of contact. After reading a couple of horror stories from people using this heatsink with quad-core processors and getting temperature differences between the cores of 10 degrees Celsius or more, I gave up any thought of getting the Ultra-120 Extreme in terror and looked for an alternative. At last, I found one heatsink with a competently designed mounting mechanism, the Ultra-X. It alone satisfies my three-point test. It's actually even better. It uses bolt-through-board-to-backplate, but instead of spring screws going into the backplate, the backplate has spikes that go through the motherboard and heatsink. (That means working with my hands further away from delicate motherboard components.) And spring thumbscrews are used (so nice!). The backplate spikes go through, and the spring thumbscrews press on, four tabs which are part of the heatsink's copper base. That means no brackets have to be screwed into the base, which is yet another bonus. It's about time!

Speaking of really good ideas, I bought some forever stamps. (I've been having to use two 37-cent stamps on each envelope, which offends my sense of efficiency.) I cannot believe how long it took for this stupid system to be fixed.

I've gotten into board gaming. My gateway was The Settlers Of Catan, which was introduced to me by my friends. I found it to be very fun, and introduced it to my parents, my sister, and her boyfriend. I got them all hooked on it, whee. Then I heard about Power Grid. Its concept and box illustration were simply too awesome to ignore, so I bought it immediately. My friends hadn't played it before, so we all got to learn how to play at the same time. Unlike Catan, Power Grid is nice in that it scales from 2 to 6 people. (Catan is played with 3 to 4 people; you need an expansion set, which I now have, to play with 5 or 6. And the nature of the game changes rather significantly when the expansion is used.) And while Catan depends strongly on rolling dice, Power Grid is much less affected by randomness. It doesn't even have dice! The game is more cerebral than Catan, so I definitely think that Catan is a much better gateway game, but my friends and I agree that Power Grid looks more interesting for very skilled players. (We've played only two games so far. I don't get out very often.)

SawStop makes me glad that I work with imaginary machines.

"Pay To Play: Uncovering Online Payola" makes me glad that I'm inherently skeptical.

"What Is The Wi Flag?" and "Turbine Squashes The Wi Flag" fill me with deep despair over the state of programming.

This Supreme Commander bug report fills me with amusement at scripting languages. (This was fixed as of 1.1.3255.) People laugh at C and C++'s insistence on variable definitions, but the joke's really on them.

6/25/2007 - I added 5 scanned novels to the SF Reviews page. I noticed that Flatland and Sphereland were hiding in my science bookcase instead of my SF bookcase. That was silly, so I moved them.

I added StatCounter to the Links page. In olden days, when evil ruled, I had visible hit counters on all of my pages. This provided some interesting information, but was hopelessly tacky. Eventually, I came to my senses and removed the hit counters. Although I maintain my own server, I've never figured out how to analyze Apache's logs, so I haven't known anything about the popularity of my pages for a very long time. I started using StatCounter last week; it provides all sorts of fascinating statistics without altering the appearance of my pages.

The relative popularity of my pages is rather disheartening; for example, my Paper Airplane page is visited much more often than my MinGW Distro. (I get the most feedback about my Origami Polyhedra page, so its popularity doesn't surprise me.) This is despite the fact that I learned how to fold that paper airplane during a couple of days in high school goofing off with my friend Aaron, while the distro is vastly more labor-intensive and useful. I know why this is the case (several paper airplane sites link to my page, and a lot more people search for paper airplanes than compilers), but that's not very comforting.

The solution, clearly, is to improve my pages. Among other things, I plan to change my rather silly rating system and begin reviewing my SF novels at a steady pace.

6/17/2007 - I removed the LASTLY and pngacc pages. LASTLY was a computer that my friend Aaron and I built back in high school to search for Mersenne primes; although it was fun, there was no real reason to have a page about it. pngacc was the second C program that I ever wrote, and it was also the last. It was intended to be faster and better than pngcrush, but it never worked properly. It collapsed under the weight of its own complexity, because manual resource management is a nightmare. Ironically, pngacc turned out to be the most important program that I've ever written, as its failure led me to abandon C and begin learning C++. For a long time, there hasn't been any reason to keep pngacc's broken source code available; nothing but evil could be learned from it, I no longer have any interest in rewriting pngcrush, and even if I did, I would use libpng instead of writing everything from scratch.

This also simplifies the site directory somewhat. It's still a horrible mess, but now it's slightly less horrible than before.

6/16/2007 - I updated the Links page yet again, adding the webcomics Dresden Codak and Erfworld. I also changed the FIPS 180-2 link.

6/10/2007 - I added 18 links to the Links page.

Also, now uses Consolas, if you have it on your computer, to display monospaced text. Otherwise, it falls back to Courier New.

Consolas is the new monospaced font included in Vista and Office 2007. If you don't have either of them, but do have Visual Studio 2005, you can download the Consolas Font Pack.

6/2/2007 - I am 24 years old today!

I have reorganized the Links page to group things in a more logical manner. I also fixed broken links, as usual.

The contents of my MinGW Distro are now listed on the webpage. README_STL.txt inside the distro has always contained the list of contents and the version history. Previously, only the version history was copied to the webpage. That was silly.

I have added scans of the Empire novels to the SF Reviews page. Now I just need to find a decent copy of Walden Two.

Finally, I revised the bottom of the Index again. It flows better now.

5/23/2007 - After allowing nearly a year and a half of news posts to accumulate, I have moved them into proper yearly archives. Doing such archiving by hand sounds so primitive, doesn't it? I should automate that.

I also revised the bottom of the Index.

5/18/2007 - My MinGW Distro has been updated. Version 2.5 contains libpng 1.2.18 (which fixes a vulnerability), as well as the final version of Boost 1.34.0. Also, gzip has been updated to 1.3.12. gunzip.exe is no more; instead, use gzip -d to decompress things. (What an obnoxious change.)

5/6/2007 - Nice wallpapers of the Carina Nebula have been added to my Image Hacking page. Single and dual 30-inch monitor versions are available; I also added such versions of the Orion Nebula. (I still have dual 23-inch monitors, but I'm looking to upgrade to dual 30-inch some day.)

Version 2.4 of my MinGW Distro includes pngcheck 2.2.0.

I added a scan of Missile Gap by Charles Stross to my SF Reviews page. Now, if I could just find the time to write some reviews....

I was somewhat surprised to discover that I had bought a signed, numbered (389 of 1000) edition of Stross's novella. I was even more surprised to notice that its cover uses the free Xirod font, which I had previously selected for my Project Which Must Not Be Named. Now I suppose I'll start seeing it everywhere.

4/5/2007 - Another week, another distro. patch.exe now works on Vista under UAC.

3/28/2007 - It turns out that GCC has been broken on Vista (see PR 30335 and PR 30972). This is fixed in version 2.2 of my MinGW Distro.

Note that patch.exe is horked under UAC due to its name. There's some manifest thing that I have to do in order to fix this; in the meantime, you can either rename it or run it elevated.

3/25/2007 - Version 2.1 of my MinGW Distro is now available. I figured out how to build wget 1.10.2, bringing me one step closer to freedom from the accursed UnxUtils.

Really awesome news: multi-processor builds finally work on Windows! (Meaning make -j 2 for dual-core, make -j 4 for quad-core, etc.) I should read release notes more often; this was fixed in make 3.81, which has been part of my distro since 6/22/2006. Note that "job server" support is still missing, so recursive make is still single-processor. On the other hand, recursive make is considered harmful, so you shouldn't be using it in the first place.

Conveniently, multi-processor builds of libnuwen's test cases work just fine. Now all I need is a quad-core machine...

3/19/2007 - What am I doing? For that matter, what are you doing?

The glib answer to the first question is, "playing Supreme Commander". That should also answer the second question, if you have any sense whatsoever.

Somewhat more seriously, this is not a question I often ask myself. Usually I get so focused on what I'm doing, I don't have time to wonder if I'm going in the right direction. This scheme has actually worked quite nicely, with a few exceptions. (I am prone to time sinks which generate neither fun nor useful work.) Still, it's probably good to come up for air once in a while.

At work, I asked myself this question after having finished Outlook 2007 Search, and didn't really like the answer. While Outlook 2007 Search was genuinely interesting and worthwhile, something can go from horribly broken to awesomely fixed only once. So at the beginning of this year, I moved to the Visual C++ Libraries team. Yup, my day job now resembles what I do for fun, except with less self-direction and more leverage. You may have already noticed my VCBlog post, although I still need to update my personal page.

At home, I asked myself this question after having finished libnuwen 2. ("But that was two months ago!", you exclaim. Well, then I had to document it, release a new distro, and catch up on random stuff that I had deferred.) Where am I going with all of this? Why do I work on my website, which consumes time and money that I could put to other uses?

It doesn't especially help that I acquired a third dimension to my life, which is now in shambles. Shocking revelation: From (very roughly) January to April 2006, I dated someone. (Long distance, but she visited Redmond at the end.) I went from being terribly confused to being convinced that things were perfect and incredible, and then she vanished with only a few minutes of conversation and a few E-mails for explanation. I still believe that explanation (that she wants to avoid relationships for the time being, not because of me, but because of other difficulties), but I don't really understand it, at least not completely. One of the things about me is that I want the power to fix things, and when I can't fix something, I at least want to understand it. It's sure nice to know that, despite everything else, I'm built like most other people in that I want something resembling a normal human relationship. It's not so nice to envision a wonderful relationship and be utterly powerless to do anything about it. And so, I wait and I hope. I seem to be extraordinarily patient compared to other people, although time passes just as slowly for me as for everyone else.

If you look closely at my old news posts, you can see where I threw myself into the libnuwen 2 rewrite after all of this happened. Now I've more or less gotten used to the fact that I'm confined to Flatland until further notice.

I have concluded that I am still going in the right direction. What am I doing? Working on my various projects. Where am I going with all of this? libnuwen 2 is a necessary step towards the Project Which Must Not Be Named (and the Project Beyond That). Why do I work on my website? It sure seems like a good idea, and I don't have any better ones.

If I am vaguely unhappy that the only website feedback I ever seem to get is about my origami polyhedra - a hobby of mine roughly 9 years ago - it must be my fault. When I step back and look at my website, what I want it to be is so much more than what it currently is. With libnuwen 2, the giant thorn in my side for years, now finished, I can turn my attention to my long-neglected pages and To Do list.

I'll apply the Supreme Commander strategy: always build more.

As it turns out, the second question ("what are you doing?") is the one implicitly posed by my pages. Perhaps you should consider it.

3/8/2007 - I've added five more books to my SF Reviews page. I also scanned a new edition of The Witling.

2/26/2007 - Version 2.0 of my MinGW Distro includes GCC 4.1.2. (I read a description of what the MinGW-local patches do and decided that I wasn't interested in them. It turns out that plain vanilla GCC works just fine.)

Aside from being more conformant, GCC 4.1.2 is significantly faster than GCC 3.4.2, both at runtime and compiletime. My BWT now runs 15% faster (from 721 to 826 KB/s) and my "puff ctor" now runs 45% faster (from 1.213 to 0.837 ms). Also, make time used to take an obnoxious 146 seconds to compile; it now takes 24 seconds. (That's 6x faster!)

Not everything about the new compiler is fluffy kittens and fuzzy bunnies; SHA-256 decreased in speed from 51.8 to 41.8 MB/s. Overall, however, I think it's pretty good.

libnuwen has also been released, fixing a minor GCC 4.1.2 warning and retuning things given the faster puff ctor.

2/25/2007 - I have completely rewritten the libnuwen documentation, although it took a month instead of a weekend.

1/28/2007 - libnuwen- (59 KB) : As foretold by the dark prophecy.

After nine months of work, the libnuwen rewrite is finally complete. The library has increased in size by 82 KB, from 246 KB to 328 KB. I'll update its documentation next weekend; for now, here's the ChangeLog entry:

[] - 1/28/2007
Rewrote all files. Complete summary of file-level changes:

private_begin.hh: Renamed to external_begin.hh.
private_end.hh: Renamed to external_end.hh.
serialize.hh: Renamed to serial.hh. Renamed to
sha1.hh: Replaced by sha256.hh. Replaced by Removed. Removed. Renamed to Renamed to
suffix_tree.hh: Integrated into bwt.hh. Integrated into
tester.hh: Renamed to test.hh. Added.
gluon.hh: Added. Added.
jpeg.hh: Added. Added.
random.hh: Added. Added.
static_assert_private.hh: Added.
traits.hh: Added. Added.

Non-exhaustive summary of individual changes:

Removed all exception specifications.
Significantly improved all tests, which now produce much more concise output.
All instantiable classes are now confined to separate namespaces.
All idempotent headers now use #pragma once on MSVC.

algorithm.hh: Provided boost::mem_fn wrappers.
arith.hh: Fixed a latent data corruption bug, triggered by INCREMENT_VALUE > 1.
          Improved BWT/MTF-2/ZLE/Arith compression from 1.684 to 1.642 b/B on suall10.txt.
bwt.hh: Removed premature generalization; suffix trees are now focused on the BWT.
        GCC 3.4.2: Decreased memory usage from 40 N to 19 N. Increased speed from 398 KB/sec to 723 KB/sec.
        MSVC 8.0 SP1: Decreased memory usage from 50 N to 19 N. Increased speed from 360 KB/sec to 728 KB/sec.
bzip2.hh: nuwen::unbzip2() now takes a single argument, allowing it to decompress actual .bz2 files.
cgi.hh: "URL encoding" is now provided in the nuwen namespace.
        Renamed nuwen::un_flat to nuwen::cgi::request.
        Fixed minor bugs in request and cookie parsing. Actually tests everything now.
clock.hh: Renamed nuwen::timeclock to nuwen::chrono::watch.
          nuwen::snooze() now uses SetWaitableTimer() on Windows, instead of evil timeBeginPeriod().
          nuwen::snooze() now uses nanosleep() on Unix, instead of evil spinning.
color.hh: Simplified nuwen::set_fore_color() and nuwen::set_back_color() on Unix.
compiler.hh: Added NUWEN_PLATFORM_FOOBAR for greater consistency.
             Added NUWEN_VERSION, which is of the form "".
external_begin.hh: Now defines NOMINMAX on Windows for greater cleanliness.
                   Now defines WIN32_LEAN_AND_MEAN on Windows for faster builds.
fibonacci.hh: Generalized to handle all unsigned integers.
              Made decoding significantly more strict.
file.hh: Moved all functions and classes to namespace nuwen::file.
         nuwen::file::write_file() now takes an output_mode.
         Added nuwen::file::remove_file().
         Files are now read in 64 KB blocks instead of 4 KB for slightly improved performance.
gluon.hh: Gluons replace the templated operators in vector.hh.
huff.hh: Decreased the puff automaton constructor's execution time on GCC 3.4.2 from 6.573 ms to 1.208 ms.
         Significantly simplified the automata and added detailed comments.
jpeg.hh: nuwen::decompress_jpeg_insecurely() wraps libjpeg. "Insecurely" refers to libjpeg's error handling,
         which exits upon fatal errors.
Makefile: Added MSVC=y DEBUG=y mode.
          Removed "make fast".
          Improved "make poison".
memory.hh: Replaced nuwen::peak_memory_usage_in_bytes() with nuwen::vm_bytes(), which is
           accurately named and useful.
mtf.hh: Removed MTF and MTF-1.
random.hh: nuwen::random::twister replaces nuwen::sha1prng.
serial.hh: Significantly restructured. The thin wrappers nuwen::serialize::serial_t and nuwen::deserialize::deserial_t
           have been replaced by the properly encapsulated nuwen::ser::serial and nuwen::des::deserial.
sha256.hh: Replaced SHA-1 with SHA-256.
           Avoided making a padded copy of the input. Added support for running the NIST test vectors.
socket.hh: Removed the non-select() server.
           Renamed nuwen::kiddy_socket to nuwen::sock::client_socket.
           Renamed nuwen::mommy_socket to nuwen::sock::server_socket.
           Simplified implementation, renamed methods, and encapsulated client IDs as nuwen::sock::client_id.
string.hh: Improved the algorithm for find-and-replace.
test.hh: The NUWEN_TEST macro gives an ID to every test and detects failed tests, thrown exceptions, and unexpected exits.
time.hh: Now handles leap seconds correctly.
         Improved the time formatting syntax; it is now readable.
         Now handles DST correctly, instead of performing all logic in UTC.
         New DST rules added; WTB [Sane Congress] x1 PST.
traits.hh: Provided simple type traits to support other headers.
typedef.hh: Systematized to generate many more typedefs. Removed evil typedefs.
vector.hh: Replaced nuwen::str_from_vuc() and nuwen::vuc_from_str() with nuwen::string_cast<T>().
           Replaced nuwen::deq_from_vec() and nuwen::vec_from_deq() with nuwen::sequence_cast<T>().
           Moved nuwen::packed_bits to nuwen::pack::packed_bits.
zle.hh: Made nuwen::unzle() significantly more strict.
zlib.hh: Added level and strategy parameters to nuwen::zlib().
         nuwen::unzlib() now takes a single argument, simplifying its use.

1/19/2007 - Version 1.13 of my MinGW Distro is now available. If you know what that is, you'll want it. Otherwise, sleep soundly in the knowledge that it speeds libnuwen to completion. And if you don't care about that (shame on you), it all supports the Project Which Must Not Be Named.

1/15/2007 - 98% done! I have fixed a rather nasty bug in the arithmetic encoder, and I improved the compression achieved by the full BWT/MTF-2/ZLE/Arith pipeline from 1.684 to 1.642 output bits per input byte (on the text file suall10.txt).

I introduced this bug over four years ago when writing bwtzip. The original arithmetic encoder in the 1987 CACM paper by Witten, Neal, and Cleary was cleaned up by Fred Wheeler into decent C, and then translated into C++ by me for bwtzip. I then cleaned it up for inclusion in libnuwen, slightly tweaked it in, and left it alone until now. The CACM and Fred Wheeler implementations used an "increment value" of 1. (Three magic numbers control the arithmetic encoder's behavior; the increment value is one of them.) One of Fenwick's BWT research papers suggested using increment values greater than 1, so I gave the bwtzip implementation this ability. Its increment value was set to 32. I wasn't paying enough attention while generalizing this deeply magical machinery, and so I introduced a data corruption bug. This bug can strike whenever the increment value is greater than 1, although it cannot strike when the increment value is exactly 1 (I didn't break the original case). Hence, bwtzip is affected (I always called it research-grade code, so I'm not too worried about it), as well as the libnuwen 1.0.22.x series. through cannot mangle data as their increment value was tuned back to 1.

I discovered all this while improving the tests for the arithmetic encoder. The old tests ran the arithmetic encoder by itself. That served as a decent correctness check, but wasn't ideal, since the entire purpose of the arithmetic encoder is to serve as the final stage in the BWT pipeline. (In contrast, the Huffman compressor is intended to be used by itself, since it is so fast. It can be used in the BWT pipeline, but produces inferior compression to arithmetic encoding.) The new tests run the arithmetic encoder both by itself and as part of the BWT pipeline. I changed the increment value several times, exploring its effect on compression, and found that a value of 64 actually produced data corruption.

Now that the bug is fixed, I am free to use arbitrary increment values. It turns out that when the arithmetic encoder is used by itself, a value of 1 gives the best compression, but a higher increment value is better for the BWT pipeline (Fenwick was right). Because the old tests didn't let me see this, I tuned it the wrong way in libnuwen The arithmetic encoder now uses a set of magic numbers that give even better compression than Fenwick's numbers, thanks to other insights I have gained. There's a nice big comment in the source explaining everything.

Also, NetHack is hard.

1/1/2007 - Well, I didn't finish rewriting libnuwen over my winter vacation. The Huffman automata needed more work than I expected, although watching Battlestar Galactica and playing Neverwinter Nights 2 weren't exactly helpful. The good news is that my Huffman decompression automaton's constructor has been sped up by 5.4x! On my computer, it used to take 6.573 milliseconds, while it now takes 1.208 milliseconds. The automata were originally based on the ideas of an acquaintance of mine (he never told me his real name, but he's credited in the source as LJM). Although I wrote all of the code myself, it felt like black magic and was hard to understand. Two and a half years later, it makes perfect sense to me. Indeed, I realized that the code was doing things in unnecessarily complicated ways, and was repeatedly computing a lot of stuff. I simplified the implementation and avoided computing things over and over, which is how I achieved the speedup.

Overall, libnuwen is 91% done. I'm so close!

My MinGW Distro and MSVC library pack have been updated to version 1.12. I replaced Boost 1.33.1 with the 1.34.0 release candidate branch, retrieved from CVS on 12/31/2006. The distro now includes every separately compiled library, instead of just Filesystem and Regex. (updated 3/3/2008)
Stephan T. Lavavej
This is my personal website. I work for Microsoft, but I don't speak for them.