From: hrubin@pop.stat.purdue.edu (Herman Rubin)
Subject: Re: A challenge to the anti-goto (C code included!)
Organization: Purdue University Statistics Department
Date: Tue, 17 Nov 1992 14:24:27 GMT

In article <nevin-171192000126@90.20.3.218> nevin@apple.com (Nevin ":-]" Liber) writes:
>In article <1992Nov5.203759.8030@linus.mitre.org>, bs@gauss.mitre.org
>(Robert D. Silverman) wrote:
>> Dr. Rubin's main rule is:

>> "The code should run as fast as possible"

>> For him, all other considerations are secondary. Who are you to tell
>> him what his priorities should be?

>Because that isn't what he is asking for.  His model of efficiency totally
>ignores OS overhead (eg page sizes, working set sizes, etc.), for instance.
> I've also never seen him deal with instruction or data caches or
>pipelining.  All of which is extremely important if you need to do the
>micro-optimisations that Herman always talks about.

I am quite aware of these problems.  I do not see any major run-time code
bloat with the optimizations I use, and I wish that hardware manuals would
do a good job of explicitly listing pipelining considerations (some do,
such as the Crays and Cybers) so that the programmer can take those into
account.

I have suggested that the compiler should communicate with the programmer
and discuss various alternatives.  The programmer, having imagination, may
then even come up with more alternatives for the compiler to consider.

>> There are times when readability, portability, and ease of maintenance are
>> of primary importance. There are times when they don't matter at all.

>Only when the results don't matter at all.

Here is part of what I would have wanted to write for my code.  Since the
languages do not allow it, and do not have the capabilities of taking into
account the information needed for fast code, *I* have to arrange it.

Comment: this code is part of a loop which will be executed many times.

	n = 0; m = 0;

irp{	g = ...;	##This point will be reached 3.08 times/loop on the
				average
	switch(g){	#*successive values are half as likely
	case 1:	n += 1; repeat;
	case 2:	exit label1;	##this most common exit (77%) has no further
					processing within the loop cycle
	cases 3, 5, 6, 9 -12:  repeat;
	case 4: h = ...; m = ib>>h; exit label1;
	case 7: h = ...; m = (ib>>1)|(ib>>h); exit label1;
	case 8: ,,,
	higher cases:  

	I will leave out the rest of the irp; it gets worse, but must be there
	There are exits to labelh and also repeats in it
	
	}

labelh:

		..................

label1:	nn[index] = n; mm[index]=m;	## End of loop

Now an optimizing compiler SHOULD certainly move the initialization to the end
of loop.   It should also move the case 1 code to before the g = ... statement,
but can it with the present restrictions?  This moves the case 1 code outside
the switch block!  Also the repeat cases all go to a location outside the
switch block, or its dropthrough.

Do you trust your compiler to do all of this?  I do not.
-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907-1399
Phone: (317)494-6054
hrubin@snap.stat.purdue.edu (Internet, bitnet)  
{purdue,pur-ee}!snap.stat!hrubin(UUCP)
Newsgroups: comp.arch,comp.lang.misc