[racket] Fun with denormalized floating point numbers
I wonder how out-of-date the advice is to avoid subnormal numbers. I
don't see any slowdown in my tests. I've written what I think is a good
test program, and I have some experience with squeezing floating-point
performance out of Racket. Can we get others on the mailing list to run
it and report some timings?
The following test program should ensure (currently) that the JIT
compiles the operations to their fastest forms, that floats don't get
boxed, and that the compiler doesn't inline 1.0.
#lang racket
(require unstable/flonum
racket/flonum
racket/unsafe/ops)
;; Don't allow Racket to inline `one':
(define (make-one) 1.0)
(define one (make-one))
;; Store floats here to make sure they don't get boxed:
(define res (make-flvector 1))
(printf "subnormal addition:~n")
(for ([_ (in-range 5)])
(time (for ([_ (in-range 20000000)])
(unsafe-flvector-set! res 0 (unsafe-fl+ +min.0 +min.0)))))
(printf "~nnormal addition:~n")
(for ([_ (in-range 5)])
(time (for ([_ (in-range 20000000)])
(unsafe-flvector-set! res 0 (unsafe-fl+ one one)))))
Running this in DrRacket, with debug info turned off, on a one-year-old
laptop, I get:
subnormal addition:
cpu time: 80 real time: 88 gc time: 0
cpu time: 100 real time: 93 gc time: 0
cpu time: 90 real time: 92 gc time: 0
cpu time: 110 real time: 106 gc time: 0
cpu time: 90 real time: 94 gc time: 0
normal addition:
cpu time: 90 real time: 87 gc time: 0
cpu time: 90 real time: 93 gc time: 0
cpu time: 90 real time: 85 gc time: 0
cpu time: 100 real time: 100 gc time: 0
cpu time: 90 real time: 93 gc time: 0
Which is obviously the same.
FWIW, subnormal numbers ensure that subtraction doesn't underflow, no
matter how close two flonums are. The smallest positive flonum is +min.0
(currently defined in `unstable/flonum'):
> +min.0
4.9406564584125e-324
Subtracting the next one from the one after returns something nonzero:
> (flstep +min.0 1)
9.8813129168249e-324
> (flstep +min.0 2)
1.4821969375237e-323
> (- (flstep +min.0 2) (flstep +min.0 1))
4.9406564584125e-324
Neil ⊥