Subject: Re: How to avoid GC in tight numeric test loop? (CMUCL)
From: rpw3@rpw3.org (Rob Warnock)
Date: Tue, 24 Jun 2008 02:50:58 -0500
Newsgroups: comp.lang.lisp
Message-ID: <0u6dnb5K8dD_Ov3VnZ2dnUVZ_oninZ2d@speakeasy.net>
Robert Maas, <jaycx2.3.calrobert@spamgourmet.com.remove> wrote:
+---------------
| Hey, because you deleted part of my address, namely the 'uh3t' part...
+---------------

It makes the line too long, and anyway, "tinyurl.com" isn't
"part of [your] address".

+---------------
| > There's special code on X86 platforms to allow args up to (EXPT 2 32),
| > *significantly* larger than KERNEL:RANDOM-FIXNUM-MAX [== 4194303 in 19c,
| > but see below re 18b!], but unfortunately the COND branch for that check
| > is in the wrong place!! [Yes, I have already mentioned this to one of
| > the CMUCL maintainers.]
| 
| Is there a patch for that which generates a FASL file which can be
| loaded into the user's environment to temporarily fix the problem
| without needing sysadmin access to re-install the CMUCL core image?
+---------------

Yes, that's how I tested it. Simply COMPILE-FILE the following
[snip between the "===" lines] and load it into your running image:

===== BEGIN "float-tran-patch.lisp" ===================
(in-package "C")

#+random-mt19937
(deftransform random ((num &optional state)
		      ((integer 1 #.(expt 2 32)) &optional *))
  "use inline (unsigned-byte 32) operations"
  (let* ((num-type (continuation-type num))
	 (num-high (cond ((numeric-type-p num-type)
			  (numeric-type-high num-type))
			 ((union-type-p num-type)
			  ;; Find the maximum of the union type.  We
			  ;; know this works because if we're in this
			  ;; routine, NUM must be a subtype of
			  ;; (INTEGER 1 2^32), so each member of the
			  ;; union must be a subtype too.
			  (reduce #'max (union-type-types num-type)
				  :key #'numeric-type-high))
			 (t
			  (give-up)))))
    (cond ((constant-continuation-p num)
	   ;; Check the worst case sum abs error for the random number
	   ;; expectations.
	   (let ((rem (rem (expt 2 32) num-high)))
	     (unless (< (/ (* 2 rem (- num-high rem)) num-high (expt 2 32))
			(expt 2 (- kernel::random-integer-extra-bits)))
	       (give-up "The random number expectations are inaccurate."))
	     (if (= num-high (expt 2 32))
		 '(random-chunk (or state *random-state*))
		 #-x86 '(rem (random-chunk (or state *random-state*)) num)
		 #+x86
		 ;; Use multiplication which is faster.
		 '(values (bignum::%multiply 
			   (random-chunk (or state *random-state*))
			   num)))))
	  ;; 2008-06-20/rpw3@rpw3.org -- BUGFIX! Swapped next two cases.
	  #+x86
	  ((< num-high (expt 2 32))
	   '(values (bignum::%multiply (random-chunk (or state *random-state*))
		     num)))
	  ((> num-high random-fixnum-max)
	   (give-up "The range is too large to assure an accurate result."))
	  (t
	   '(rem (random-chunk (or state *random-state*)) num)))))
===== END "float-tran-patch.lisp" ===================


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607