Hello,
I am rather new to lisp, I'm still learning the basics, but I hit on a
suprising behaviour of cmucl - I hope that somebody will explain what's
the problem and how to avoid it.
I wrote a simple program to calculate probabilities of various results
of dice roll in a RPG game. It is pure brute force - it just checks all
possible combinations of number of dies and records what result given
combination represents (I know that it is not the most effective
method, not even effective implementation, but that's not the
problem). It worked fine, on my machine completes in about eight
seconds. Then I tried to improve it a bit, and added element type
declarations to the make-array statements, hoping that it will allow
the compiler to generate more effective code. However, to my suprise,
runtime increased to almost 11 seconds. What is the problems?
Another problem I have with cmucl: I tried to install it on another
machine - PIII, 384MB RAM, 512MB swap, Linux 2.4.19 with some patches
(but almost same as the other machine, except for some drivers), same
distribution (Gentoo Linux), same version of cmucl (18d, binaries from
distribution site) - and it simply does not works. Few moments after
startup it says "Segmentation fault" and crashes back to the command
line without any more messages. I tried "echo 1 >
/proc/sys/vm/overcommit_memory" suggested in the faq, but without
success...
I hope these questions are not too stupid and that somebody will help
me :-)
regards,
Bob Koutsky
follows my dice-rolling program with :element-type declarations added:
(defconstant *sides* 10)
(let ((r (make-array *sides* :element-type 'fixnum)))
(defun check (dice num succ fail botch)
; reset counters
(dotimes (i *sides*)
(setf (aref r i) 0))
; scan dices
(let ((ones 0))
(dotimes (i num)
(if (= (aref dice i) 0)
(incf ones)
(progn
(loop for j from (aref dice i) downto 1
do (incf (aref r j))))))
; record results
(dotimes (i *sides*)
(cond
((> (aref r i) ones) (incf (aref succ i)))
((and (> ones 0) (= (aref r i) 0)) (incf (aref botch i)))
(t (incf (aref fail i))))))))
(defun increment (dice num)
(loop for i from 0 below num
do (incf (aref dice i))
when (>= (aref dice i) *sides*) do (setf (aref dice i) 0)
else do (return-from increment nil)
finally (return-from increment t)))
(let* ((num 6)
(dice (make-array num :initial-element 0 :element-type
'fixnum))
(succ (make-array *sides* :initial-element 0 :element-type
'fixnum))
(fail (make-array *sides* :initial-element 0 :element-type
'fixnum))
(botch (make-array *sides* :initial-element 0 :element-type
'fixnum)))
(format t "Start...~%")
(loop
do (check dice num succ fail botch)
until (increment dice num))
(princ succ) (princ #\Newline)
(princ fail) (princ #\Newline)
(princ botch) (princ #\Newline)
(quit))