I’m Old, Part XL: When Cycles Mattered

When I was 20, I took a year off college and worked at Bell Communications Research. I was a contractor and worked in a group that was doing, primarily, human computer interfacing research. Within the department, most of the people worked on Sun 3 workstations which were running on a 68020 at about 16MHz with a 1 bit display. It came with a windowing system, SunTools, which ran like a dog.

This was a different era for computing. Men were real men. Women were real women. And small furry creatures from Alpha Centu…sorry. And every cycle mattered if you wanted an app that didn’t run like a dog.

There was an engineer in the group named Steve Uhler, who had a wonderfully refreshing love/hate attitude towards these machines. He couldn’t stand SunTools, so he wrote his own windowing system, MGR. It was built to squeeze as many cycles out of the CPU as he could manage without reverting to assembly and it had a very interesting mode of operation. Most windowing systems at the time were written so that they had to run natively on the CPU of the computer. X had ways of running on a different machine, but early on it didn’t work particularly well. Instead, MGR ran on your local system and programs that wanted to use graphics would use a set of macros that generated escape codes to perform graphics operations on the windowing system. Essentially, if you wanted to draw a line, you did a printf(). To make your life easier, Steve made a bunch of macros which did that for you. In addition to basic graphics, there were higher level routines that could make new windows, make menus, resize windows, move windows, and so on.

Under the hood, Steve had written some really intense C to make sure that this all happened very quickly. In his bit-blitting code, he had macros that unrolled the loops that in turn had macros that handled various bit-level operations (AND/OR/XOR/etc). The code ran very, very quickly and as a result the UI felt very snappy. In addition, Steve had an interesting solution to the “partially obscured window” problem. Most systems are built to not care about obscured windows and notify the app when they’ve been uncovered so the app can repaint the window. Not Steve. He kept a backing store for each window and all operations went into the backing store. When a window was exposed, he just blitted the backing store on top and ta-da, the window was there. His code also routinely broke C preprocessors. I mentioned early that Steve had a love/hate attitude and he loved to hate compilers. If the department got a new machine or there was a new better C compiler, Steve would break it and complain with a smile.

The cool thing was that if you had some serious number crunching to do, you could do it on a serious number crunching computer and #include the MGR header for spitting out the graphics. It worked astoundingly well.

I wrote a ton of code for MGR, including a UI front end to gnuchess, a higher level UI library for doing dialog boxes and control widgets, a tool to display the output of pic, Hinton diagram display code, and a raft of graphics hacks including a hack that had a bunch of walking eyeballs.

I also ported MGR to the Macintosh. That was interesting because, while Steve’s bit-blit code worked on the Mac, it didn’t run as well as native Mac apps. This shouldn’t have been a surprise. The Mac I used ran at 8MHz, not 16MHz and had a 16 bit data bus not a 32 bit data bus. Also the QuickDraw, the native graphics API was written in carefully tuned assembly language. So I found the bottlenecks into Steve’s bit-blit code and replaced them with QuickDraw calls and hooray everything worked and ran close to the same speed as the Sun.

And while I enjoyed shaving cycles in my code, I don’t miss it all that much. Yes, I know that software has bloated to fill memory and CPU capacity, but at the same time it’s very straightforward today to run a decent profiler, find the main hot spots and cool them off. And this can typically be done in a way that doesn’t compromise the readability or intent of your code.

The last time I talked to Steve, he was working on research projects related to the Java VM. He had the same love/hate attitude while he was talking about work that tracked local variables and code that he put in to make them get stack allocated instead of heap allocated so you wouldn’t burden the garbage collector with things that were short-lived and guaranteed to be collected and method exit.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.