A directory mp was added to hold the new multi precision arithmetic
code. The layout and a fair amount of code in the mp directory is an
enhanced version of gpari version 34. The gpari c code was rewritten
to be more efficient, and gcc assembler macros were added to allow
inlining of operations not possible to do in C. On a 68K machine,
this allows the C version to be as efficient as the very carefully
written assembler in the gpari distribution. For the main machines,
an assembler file (produced by gcc) based on this new method, is
included. This is for sites which do not have gcc, or do not
wish to compile the whole system with gcc.
Bignum arithmetic is much faster now. Many changes were made to
cmpnew also, to add 'integer' as a new type. It differs from
variables of other types, in that storage is associated to each such
variable, and assignments mean copying the storage. This allows a
function which does a good deal of bignum arithmetic, to do very
little consing in the heap. An example is the computation of PI-INV
in scratchpad, which calculates the inverse of pi to a prescribed
number of bits accuracy. That function is now about 20 times faster,
and no longer causes garbage collection. In versions of AKCL where
HAVE_ALLOCA is defined, the temporary storage growth is on the C
stack, although this often not so critical (for example it makes
virtually no difference in the PI-INV example, since in spite of the
many operations, only one storage allocation takes place.
Below is the actual code for PI-INV
On a sun3/280 (cli.com)
Here is the comparison of lucid and akcl before and after
on that pi-inv. Times are in seconds with multiples of the
akcl time in parentheses.
On a sun3/280 (cli.com)
pi-inv akcl-566 franz lucid old kcl/akcl
----------------------------------------
10000 3.3 9.2(2.8 X) 15.3 (4.6X) 92.7 (29.5 X)
20000 12.7 31.0(2.4 X) 62.2 (4.9X) 580.0 (45.5 X)
(defun pi-inv (bits &aux (m 0))
(declare (integer bits m))
(let* ((n (+ bits (integer-length bits) 11))
(tt (truncate (ash 1 n) 882))
(d (* 4 882 882))
(s 0))
(declare (integer s d tt n))
(do ((i 2 (+ i 2))
(j 1123 (+ j 21460)))
((zerop tt) (cons s (- (+ n 2))))
(declare (integer i j))
(setq s (+ s (* j tt))
m (- (* (- i 1) (- (* 2 i) 1) (- (* 2 i) 3)))
tt (truncate (* m tt) (* d (the integer (expt i 3))))))))