[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

block compilation and benchmarking, maybe ad nauseum



Apropos your remark about block compilation.

Below are statistics comparing block compilation in CMU Lisp with
ordinary, but proclaimed, compilation in AKCL.  (There is no block
compilation in AKCL.)  The machine is a Sparc 2.  The test is of a
call and execution of a function of 0 args, which merely sets a global
variable to its negation.  (I had the function ``do'' something this
time, rather than just return its arg, to avoid block-compilation
completely optimizing it away, as it did calls to my function foo of
the previous example, as you indirectly pointed out.)  It looks like
AKCL is about 24% faster here.

Can one redefine functions wired inside a block?  One couldn't in
Interlisp-10.  In ACKL, one can certainly redefine, e.g., trace a
proclaimed function.  I believe one must respect the proclamation,
however.

As you have several times pointed out, I realize that you have not
optimized for the SPARC.  I'm just not convinced that native code
optimiation for a Lisp is likely to produce results that are *better*
than what the C compiler does on a Unix system for simple things like
function call and assignment to a global.  Nothing against Lisp, but
rather just a comment on the sheer numbers of clever people interested
in optimizing C compilers.  So, to continue the line of thought, to
the extent that AKCL manages to turn a Lisp operation (e.g., a
function call, setq, arithmetic or logical operation), into a
corresponding C operation, one would not expect to beat AKCL with a
native code Lisp.

I've put a compressed binary for AKCL 1.530 (the one I was running) in
/pub/kcl/sparc-akcl-1.530-binary.Z, visible by anonymous ftp, which
you can ftp if you've any interest in comparing things yourself.
(This is not the very most up to date AKCL.  That's 1.603 I think, and
you can get the sources for that from cli.com and do a build yourself,
but I don't have an assembled binary of it handy.)  I think the file I
mentioned is a complete stand-alone AKCL for Sparc (assuming you have
a ``cc''), but I'm not absolutely sure since I'm not really
knowledgeable about these things.  Hope Schelter will correct me on
this if I'm wrong.

-------------------------------------------------

(report 10000000) for cmulisp (beta) on a sparc 2 with (compile-file
"foo.lisp" :block-compile t :entry-points '(report))

do-cost
Evaluation took:
  1.52 seconds of real time
  1.52 seconds of user run time
  0.0 seconds of system run time
  0 page faults and
  0 bytes consed.
regular-call-cost
Evaluation took:
  10.82 seconds of real time
  10.56 seconds of user run time
  0.0 seconds of system run time
  0 page faults and
  0 bytes consed.
funcall-cost
Evaluation took:
  10.88 seconds of real time
  10.87 seconds of user run time
  0.01 seconds of system run time
  0 page faults and
  0 bytes consed.


(report 10000000) for
akcl 1.530 (compile-file "foo.lisp")

do-cost
real time : 1.400 secs
run time  : 1.283 secs
regular-call-cost
real time : 8.650 secs
run time  : 8.567 secs
funcall-cost
real time : 10.117 secs
run time  : 10.117 secs

-----  the file ---


(proclaim (quote (optimize (compilation-speed 0) (safety 0) (speed 3) (debug 0))))

;  Proclaim that function foo takes 0 values and returns one.
(proclaim '(function foo () t))

(defparameter *v* nil)

(defun foo () (setq *v* (not *v*)))

(defun do-cost (n)
  (do ((i n (1- i))) ((= i 0))
      (declare (fixnum i))
      3))  ; Do nothing.

(defun regular-call-cost (n)
  (declare (fixnum n))
  (do ((i n (1- i))) ((= i 0))
      (declare (fixnum i))
      (foo)))  ;  Call foo in the ordinary way.

(defun funcall-cost (n fn)
  (declare (fixnum n))
  (do ((i n (1- i))) ((= i 0))
      (declare (fixnum i))
      (funcall fn)))   ;  The value of the funcall is ignored. 

(defun report (n)
  (format t "do-cost")
  (time (do-cost n))
  (format t "regular-call-cost")
  (time (regular-call-cost n))
  (format t "funcall-cost")
  (time (funcall-cost n #'foo)))