Marc:
I was looking at the mbrot benchmark with unsafe fixnum and flonum operations; the main loop is
Loop 1:
(define (count r i step x y)
(let ((max-count 64) (radius^2 16.0))
(let ((cr (fl+ r (fl* (exact->inexact x) step))) (ci (fl+ i (fl* (exact->inexact y) step))))
(let loop ((zr cr) (zi ci) (c 0)) (if (fx= c max-count) c (let ((zr^2 (fl* zr zr)) (zi^2 (fl* zi zi))) (if (fl> (fl+ zr^2 zi^2) radius^2) c (let ((new-zr (fl+ (fl- zr^2 zi^2) cr)) (new-zi (fl+ (fl* 2.0 (fl* zr zi)) ci))) (loop new-zr new-zi (fx+ c 1))))))))))
Recomputing floating-point results is often faster than boxing them, so I applied this to zr^2 and zi^2, to get
Loop 2:
(define (count r i step x y)
(let ((max-count 64) (radius^2 16.0))
(let ((cr (fl+ r (fl* (exact->inexact x) step))) (ci (fl+ i (fl* (exact->inexact y) step))))
(let loop ((zr cr) (zi ci) (c 0)) (if (fx= c max-count) c (if (fl> (fl+ (fl* zr zr) (fl* zi zi)) radius^2) c (let ((new-zr (fl+ (fl- (fl* zr zr) (fl* zi zi)) cr)) (new-zi (fl+ (fl* 2.0 (fl* zr zi)) ci))) (loop new-zr new-zi (fx+ c 1)))))))))
Results:
Default heap:
Loop 1:
./mbrot
code size = -289 (time (run-bench name count ok? run)) 1792 ms real time 1791 ms cpu time (1770 user, 21 system) 12549 collections accounting for 1499 ms real time (1487 user, 10 system) 2782878336 bytes allocated 44 minor faults no major faults
Loop 2:
./mbrot
code size = -289 (time (run-bench name count ok? run)) 794 ms real time 793 ms cpu time (785 user, 8 system) 5166 collections accounting for 619 ms real time (614 user, 4 system) 1147411712 bytes allocated 44 minor faults no major faults
But increasing the heap from whatever the default is to 1MB (roughly) made an even bigger difference on my machine (2.4GHz Intel Core 2 Duo, Mac OS X 10.6.8):
Loop 1:
./mbrot -:m1000
code size = -289 (time (run-bench name count ok? run)) 536 ms real time 535 ms cpu time (530 user, 6 system) 2440 collections accounting for 296 ms real time (293 user, 2 system) 2782736064 bytes allocated 343 minor faults no major faults
Loop 2:
./mbrot -:m1000
code size = -289 (time (run-bench name count ok? run)) 289 ms real time 289 ms cpu time (286 user, 3 system) 1000 collections accounting for 121 ms real time (120 user, 1 system) 1147581952 bytes allocated 343 minor faults no major faults
Surely 1MB can be OK as a default heap size nowadays ;-)!
This is with
gsc -v v4.6.6 20120915144211 i386-apple-darwin10.8.0 "./configure 'CC=/pkgs/gcc-4.7.2/bin/gcc -march=core2 -fschedule-insns -frename-registers' '--enable-single-host' '--enable-multiple-versions'"
Brad