Path: utzoo!mnetor!uunet!husc6!yale!leichter From: leichter@yale.UUCP (Jerry Leichter) Newsgroups: comp.lang.c Subject: Re: Another way (How not to write a loop) Message-ID: <23450@yale-celray.yale.UUCP> Date: 19 Feb 88 18:43:00 GMT References: <1988Feb11.200149.25172@sq.uucp> <2550046@hpisod2.HP.COM> <2150@bsu-cs.UUCP> <7285@brl-smoke.ARPA> Reply-To: leichter@yale-celray.UUCP (Jerry Leichter) Organization: Yale University Computer Science Dept, New Haven CT Lines: 86 Commenting about the inplementation of SPITBOL/360, which used a floating point register to keep track of the number of statements executed, Doug Gwyn writes: > >So, the Snobol implementor made a stupid decision, then. > He the proceeds to explain that the decision was stupid (a) because when he compared two ways of doing this on a Gould Powernode, doing it with integers was faster; (b) the way SPITBOL did it was "non-portable". It's generally a good idea to understand the issues before criticizing a design decision. Neither Doug's comments, nor any of the others on this topic, are based on any such understanding. They appear to be made by people who don't understand the language, the implementation environment, the goals of the implementation --- the probably don't even know to within 5 years when the implementation they are criticising was done. How anyone can have the chutzpa to imagine that they have ANYTHING worthwhile to say, lacking all that basic information, would be beyond me if I hadn't seen so much flammage on this net already. To add a little reality: SPITBOL/360 was done somewhere around 1971. It was an attempt to produce a complete implementation of all of SNOBOL4 that would run as fast as possible. There was already a very portable --- certainly by the standards of the late 1960's, probably even by today's standards --- im- plementation of SNOBOL in existence. It took, by the standards of the day, a huge amount of memory, and ran slowly. SPITBOL attempted to address both constraints. It was willing to forgo portability, and was designed to run on IBM/360's --- yes, 360's, the 370 wasn't to exist for several more years --- under OS/360. Now, SNOBOL4 is not an easy language to execute efficiently. It allows for things like the creation of new functions, data types, and even variables at run time --- and these abilities are heavily used. It allows new code to be compiled at run time, sometimes replacing existing code. Assignments to, or even attempts to read from, variables can trigger I/O, or (via tracing) the execution of arbitrary user code. The fact that a particular access to a particular variable may have such affects can only be determined at run time. Enough generalities. The particulars of the use of a floating point statement counter are as follows: Floating point arithmetic is quite rare in SNOBOL programs, so there is little to be gained by keeping FP registers --- and remember, on a 360 FP registers are completely distinct from the general registers --- free. On the other hand, the nature of SNOBOL, and the way addressing works on a 360, places a premium on general registers. Also, in the early '70's, core was CORE --- registers were MUCH faster than main memory. Even FP registers and FP operations were quite fast compared to main memory accesses. Now, SNOBOL numbers statements, and it counts statements executed. The statement count must be checked at the beginning of every statement executed against a (user-changable, at run time) statement limit. The statement number, on the other hand, is only used in rare circumstances --- in generating errors, or in the (in practice) unlikely event that the user asks for it. So the SPITBOL implementors did something clever: They used an otherwise-unneeded resource (an FP register) in a clever way to solve several problems. The counter was kept in the FP register, and the hardware effectively did the statement limit check. Meanwhile, the actual instruction used --- an AUR, as Rahul Dhesi noted, Add Unnormalized Register --- was "unusual"; in fact, it was never generated by the compiler anywhere but at the head of a statement. Thus, it acted as a "statement begin" marker. No record was kept of the current statement number --- doing that would have required tying up another register, or an extra memory access, at each statement. Instead, on the rare occassions that the current statement number was needed, the run-time code would walk through all the compiled code --- it was all linked together --- and count AUR's until it got to the currently-executing statement. I believe there may have been other instances in which it was necessary to find the beginning of the current, or the next, statement; searching for an AUR could be used for that, too. All told, an elegant, effective, and fast solution, given the realities of the day. Some of the same people who design SPITBOL/360 later went on to develop MACRO/SPITBOL, a rather interesting implementation that was designed to be (a) portable; (b) efficient on any particular hardware. It succeeded; MACRO/SPITBOL on a PDP-10 was smaller, and usually faster, than SITBOL, an implementation that had been hand-tuned for the -10. MACRO/SPITBOL, now at least 10 years old, continues to be available; it runs on such machines as VAXes and 8086's, both designed well after the implementation. -- Jerry