Presented at the Sumeria Technology and Issues Conference, 30-Jun-94
This paper is a case history of the development of RAM Doubler 1.5, the Power Mac-compatible version of the popular Connectix memory management utility, RAM Doubler 1.0.
We began work on the PowerPC version of RAM Doubler in the fourth quarter of 1993, when we entered the final stages of the 68K development. Our initial target for the port release was the third quarter of 1994. We're on schedule and expect to release the final version within about a month. This port was the twenty-third major software development in the firm's history and was one of our most successful projects in terms of schedule, budget, and performance to specification. This paper gives our perspective on some of the obstacles we had to overcome and why things went well.
First, I should point out that our problems were somewhat different from those of a mainstream application developer. RAM Doubler is a specialized utility which is both easier and harder to port than a major application. On the plus side it's small; the total code base is less than 40K, so the number of lines of code to be rewritten is limited. On the minus side the nature of the product is that it modifies the operating system at the most basic levels and cannot be readily ported with standard translators. RAM Doubler 1.0 is one of the few mass volume products in today's market that won't work at all in emulated mode. So the amount of work per line of code was relatively high. (And the urgency to develop a Power Mac-compatible version was equally high!)
Here are the main things we learned in doing the port:
Apple really can and will help.
Start with a solid 68K foundation.
Port first, improve later.
Modularize the project.
Deal with motivational issues.
Apple really can and will help! Over the past 6 years Connectix has watched the evolution of Apple's third-party relationships. On the whole the trend is positive with a greatly reduced "Not Invented Here" quotient and a general increase in understanding of what developers need to do their work. I want to thank the PowerPC software team in particular for spending two hours with us in March thumbing through the source code answering specific questions were stuck on at that crucial stage of the project. It probably saved us a month on our critical path and was time they could barely afford at that point. The lesson is that Apple has a vested interest in getting good PowerPC-native software out there fast and you should look to them for all the help you can get.
Start with a solid 68K foundation. This is obvious but easy to overlook. The temptation is to postpone your last major maintenance revision and roll it into the PowerPC project. This is a major mistake! You will definitely introduce new bugs into your code in doing the PowerPC-native port and the last thing you want to be doing is sorting out old bugs from new ones. Debugging time increases exponentially with the number of unresolved bugs present at any one time, so clean up the 68K code before you port, no matter what you think that will do to your critical path timeline.
Port first, improve later. This is probably the most important decision we made and it paid off. Just as with maintenance, there's a natural inclination to take advantage of a major revision such as a port to "finally do it right." There will be plenty of algorithms, implementations, or features that seem stale in the old 68K code and which your team will want to improve. The problem, again, is that you'll have to regress new bugs not knowing if they came from translating your stable 68K code base, or in adding the new PowerPC-specific code. The surprisingly large diseconomies of scale in debugging argue strongly in favor of doing a straight port first and an improved product second. This is true even if you don't plan to release the intermediate version.
There were many examples in our code where we would have liked to rewrite huge sections for PowerPC. Two specific examples were our system patches, which we believed should be native, and our aging table updates, where we knew that our old procedure would probably be too slow in the PowerPC-native version, or rather not enough faster to keep up with the other very fast PowerPC code. What we found, to our surprise, was that although the aging process needed to be reworked, our system patches were not a performance issue. By making the port the first priority, we were able to make moderate changes in the standard algorithm, achieve very good performance, and minimize the technical risks associated with going to a new approach. The ultimate code was at least as fast as we believe the new method would have been.
There are plenty of reasons not to expand the goals of the product in the port. Your team must learn new development tools, cope with a new environment and discover a whole new set of gotchas that don't exist in 68K. There's no reason to add to this burden by specing new features, debugs of old problems or improvements of working implementations. Besides if you do, you'll have to go back to the old 68K code and fix it later anyway, so you don't save much time.
Now, I should point out that this central point may be specific to the system software and utility side of the business. If you look at the two largest developers of Mac software, Apple and Microsoft, you'll see opposite approaches. Apple essentially followed the strategy we just described in shipping the first OS for PowerPC, preferring to introduce major feature revisions in the first update. Conversely, Microsoft has announced a major feature revision in concert with their major applications ports. I'm not sure how this affected the relative release schedules.
Modularize the development. The exponential rule of debugging implies that if you can tackle 100 bugs ten at a time it will take a tenth as long as taking them all on at once. So for this reason alone, it's especially critical in such a bug-intensive project as a PowerPC port to modularize the development. There's another benefit, too. You can start by working on the sections of the code that will make the product feel faster first and leave the secondary work for later. Using the 80/20 rule this way motivates the development team in the hard, early stages with tangible results.
Of course, by modularizing a system-level product, you may end up with a mixed 68K and PowerPC product. There are two disadvantages of shipping mixed code. First, mixed-mode switches between the 68K and PowerPC worlds require running 40-50 instructions. In the case of a speed-oriented product like RAM Doubler this is often unacceptable, but in many cases it's quite tolerable. Second, there's an unfortunate growing perception in the user community that a good PowerPC product must be 100 percent native (like 100 percent cotton or 100 percent Columbian coffee) to be a quality package. So there's a marketing problem to solve that's largely independent from the true performance of the code.
Deal with the motivational issues. If you follow the strategy we've outlined risk of making the project seem like it's "just a port" and therefore not particularly sexy. You'll probably need your best engineers who know the most about your most valuable code heavily involved in the project to make it come out well. Half the battle here is just recognizing the issue up front and putting a little extra energy into showing appreciation for the work. You must make a special effort to provide this team with the best available hardware - (our guys got their 8100s before the VPs did) - and don't forget to keep the engineering refrigerators amply supplied with Jolt cola and doughnuts!
Be flexible. On several occasions we had conflicting views on how to code a particular problem. Rather than having meetings and involving lots of people to determine the best answer, we let two independent teams work on their respective views. Much of the time, before the work was done, one team would give in and admit to the other's better approach. In other cases, both teams would produce adequate results, which might be presumed as wasteful. However, even in these cases we wasted remarkably little effort, because the two teams would often run into different sets of bugs that nonetheless affected each other. When we combined the two solutions, the result was a far more solid solution than what either team could have done independently.
Share the glory. We get about twenty letters a day from RAM Doubler users who love our product. About four months ago we started collecting them, highlighting the best phrases and leaving them on a counter outside the RAM Doubler engineering area. It's a small touch but has a big impact on morale and, ultimately, productivity. Whenever a difficult problem arises these letters serve to pick up the spirits of the team and remind people what a good job they do.
Be realistic. There are two ways to manage deadlines in a development project, and the right one depends on the personalities you work with. The traditional approach is to impose a tough deadline which in retrospect was unachievable but which theoretically squeezes out the fastest possible result, at the expense of higher burn-out. For Connectix, a better way seems to be to set a reasonable deadline, state up front that you know it can't possibly be met and then, as often as not, your team beats it to prove you wrong. In any case that's what happened with RAM Doubler 1.5.
On that note, let me take just a minute to help you imagine a quick demo. This is an 8 MB Power Mac 6100 launching SoftWindows into an RAM doubled 16 MB partition. While opens, I'll mention that the comparable benchmark is 34 seconds to launch this on a true 16 MB Mac. I won't to bore you by making you wait the 112 seconds it would take to do this running 8 MB and System 7 Virtual Memory. There - if you were timing you got a total time of 37 seconds, less than ten percent slower than the pure RAM case. And this is one of the worst performance cases we've uncovered. Our general performance vs. true RAM is 99 to 99.5 percent the speed, because the PowerPC is perfectly suited to the computation-intensive operations of memory management and compression that RAM Doubler uses.
This demo was ready for the Sumeria conference because we adhered to five main principles: let Apple help, start with stable code, port first, improve later, modularize the project, and deal with the motivational issues. RAM Doubler 1.5 will be available in early August, is compatible with both 68K and PowerPC, is a free upgrade from the earlier 68K-only version and continues to carry a list price of $99. For more information on this or any other Connectix product you can reach us on the net at <firstname.lastname@example.org>, or by phone at 800/950-5880. Now, on to the Windows version...