Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.2 9/18/84; site harvard.ARPA
Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!macrakis
From: macrakis@harvard.ARPA (Stavros Macrakis)
Newsgroups: net.ai,net.lang.lisp,net.lang.ada
Subject: Speed with numbers: PDP-10 Maclisp vs. Fortran (details)
Message-ID: <470@harvard.ARPA>
Date: Wed, 13-Mar-85 15:00:45 EST
Article-I.D.: harvard.470
Posted: Wed Mar 13 15:00:45 1985
Date-Received: Tue, 19-Mar-85 14:28:24 EST
References: <417@ssc-vax.UUCP> <676@topaz.ARPA> <6982@watdaisy.UUCP>
Organization: Aiken Comp. Lab., Harvard
Lines: 81
Xref: watmath net.ai:2615 net.lang.lisp:384 net.lang.ada:227

> [perhaps] the original test [was] against the old DEC Fortran
> compiler, F40. .... This particular piece of folklore (that Maclisp
> generates as good code as Fortran) is more widely quoted than you
> might think.  If it isn't true, or if the Fortran compiler is one that
> would now be viewed as substandard, I would very much like to know.

It's not true.  What is true is that in some cases (heavy use of
procedures, light use of arrays), Maclisp can hold its own.  The Fortran
compiler being used was not great, but then the Maclisp compiler is
old-fashioned as far as compiler technology goes, too.

Now for the details: you asked for them....  Inner loop times only.  All
execute the same floating-point instructions, so the number of memory
references plus the number of multiplications (for 2D indexing) is a
good measure of time.

	  Version	Date	Inner prod   Sum up 2d array

F10/Opt	  V.1A	        76	   6	      6
F10	    "		76	   7	      9 + Mul
F40	  F40I V27(360) 76	   8	     10 + Mul
Maclisp	  1135	        83	  23	     16 + Mul

Note that the problems are chosen to emphasize Fortran's strength with
arrays.  In straight-line numerical code, Maclisp will do relatively
better, but still not as well as the Fortrans.  Maclisp has faster
procedure call/return as well: the DEC Fortrans take about 
	11 + 7 * arg + 3 * out-arg
mem refs, while Maclisp can take as little as
	 4 + 1 * arg ,		(if args stay in registers)
although more common is
	 6 + 3 * arg .		(if args are stashed on stack)
It is this advantage in procedure calling that was largely responsible,
if I remember correctly, for the good Lisp results in the Sigsam article
(sorry, I don't have the reference: something like 1977).  Of course,
the Fortran arguments are by-reference, and the Lisp by-value; and the
register conventions differ.  There are other, hidden, overheads in the
Lisp use of arrays, namely that in Maclisp (at least), they can neither
be stack-allocated nor statically-allocated, but rather come out of a
heap, increasing allocate/deallocate overhead.

As always, remember that all languages have their strengths and
weaknesses, that a language may have good implementations and bad, and
that speed is only one consideration.

	-s


Appendix

For your delectation, the Lisp and Fortran code, and F10/opt's output.
Note that the Fortran source is much clearer in this case, too.

Sum up 2d array

	(do ((i 0 (1+ i))) ((>= i 1000))
	    (do ((j 0 (1+ j))) ((>= j 1000))
		(setq sum (+$ sum (a j i)))))

	DO 10 I=1,1000
	  DO 10 J=1,1000
10	    SUM=SUM+A(J,I)

8M:	MOVEI	14,0(15)
	ADD	14,.O0000	; should have put .O0000 in register
	FADR	2,A-13(14)
	AOBJN	15,8M

Inner product

	(do ((i 0 (1+ i))) ((>= i 1000))
	    (setq sum (+$ sum (*$ (b i) (c i)))))

	DO 20 I=1,1000
20	   SUM=SUM+B(I)*C(I)
	END

10M:	MOVE	14,B-1(15)
	FMPR	14,C-1(15)
	FADR	2,14
	AOBJN	15,10M