[Openmcl-devel] how does one cause stack-allocation for floats?

Gary Byers gb at clozure.com
Tue Mar 28 08:35:00 PST 2006


There is no advertised, supported mechanism for "stack allocating floats"
or for doing destructive operations on them in OpenMCL, and I hope that
there never will be: it's the wrong idea and it's too easily abused.

It would certainly be good if the compiler was smart enough not to
cons (sometimes hysterically) intermediate floating-point results (and
therefore had some notion of what was intermediate and what was
long-lived).  Exposing destructive operations to the user (and possibly
conflating assignment with those destructive operations as I think has
been done in MCL) doesn't make the compiler smarter.

? (time (let* ((sum 0.0d0))
         (dotimes (i 1000000 sum) (incf sum i))))
(LET* ((SUM 0.0D0)) (DOTIMES (I 1000000 SUM) (INCF SUM I))) took 201 milliseconds (0.201 seconds) to run.
Of that, 198 milliseconds (0.198 seconds) were spent in user mode
          2 milliseconds (0.002 seconds) were spent in system mode
          1 milliseconds (0.001 seconds) were spent executing other OS processes.
4 milliseconds (0.004 seconds) was spent in GC.
  16,000,000 bytes of memory allocated.
4.999995D+11

The deep dark secret here is that there is some stack-allocation of 
double-floats (and destructive modification or them) going on.  That
and all of the other overhead (generic arithmetic, several layers
of function calls to do the implicit (COERCE I 'DOUBLE-FLOAT), ...)
are apparently taking about 50X longer in this case than what the
stack-allocation/destructive operation is trying to minimize (GC
overhead.)

All other things being equal, not consing hysterically (and therefore
not spending any time in GC) is certainly better than doing either or
both of those things.  It seems pretty clear that there's a lot of
other overhead here (a lot of function call overhead, a lot of type
dispatching, and a lot of unnecessary memory traffic, among other
things.)  It's certainly desirable to eliminate as much as possible
of this overhead, and doing so (making the compiler more aware of
what's going one, e.g., inlining the arithmetic) is a necessary
step towards eliminating the unnecessary consing.

(For the record, "gcc -O5" produced something that ran in about
16 milliseconds, and something that I wrote in LAP ran in about
3 milliseconds.  There's clearly some room for improvement here.)

There are undoubtedly cases where memory-allocation overhead is more
significant than it is in the example above, but I really don't want
to expose, support and/or advocate destructive floating operations.
Aside from that having very little to do with a real solution (more
smarts in the compiler) and offering fascinating ways to lose (by
turning the constant 0.0d0 into PI ...), it's a maintenance headache:
in 64-bit versions of OpenMCL, SINGLE-FLOATs are immediate (32 bits
of data fit in a 64-bit machine word with lots of room to spare),
Since it makes no sense to talk about destructive operations on
immediate objects and since a lot of internal 32-bit code uses
destructive operations and stack-allocation to avoid (some)
SINGLE-FLOAT consing, practically every primitive that could
produce a SINGLE-FLOAT result (and every caller of those primitives)
comes in 2 flavors.  If the compiler were inlining those primitives,
then I think that there'd be far less reason for the runtime version
to jump through as many hoops, and that would offer a good excuse
to drop the internal/unsupported runtime support for destructive
FP operations.

On Tue, 28 Mar 2006, james anderson wrote:

> hello;
>
> i last asked about this months (years?) ago and recall that the answer was, 
> "eventually".
> unfortunately, that mail archive is not any more and, fortunately, open-mcl 
> is at least .5 versions further, so i ask again.
>
> ?
> 1. how does one get open-mcl to stack-allocate floats?
> i was not able to find any suggestions in the documentation, so, if i missed 
> it, please send the pointer.
>
> 2. is the timing difference just consing overhead?
>
>
> i enclose a simple test file. nothing obvious seems to work.
> a listener transcript follows and the file is attached below.
>
> thanks,
> ...
>
> --------------
>
> Last login: Mon Mar 27 21:59:05 on ttyp5
> /Applications/LISP/openmcl/ccl-1.0/dppccl64; exit
> Welcome to Darwin!
> dev219-m:~ janderson$ /Applications/LISP/openmcl/ccl-1.0/dppccl64; exit
> Welcome to OpenMCL Version 1.0 (Beta: DarwinPPC64)!
> ? (compile-file "/Volumes/slapl01/Home/janderson/Source/ravenpack-dev/ 
> EconoRavenLisp/tests/float-tests.lisp")
> #P"/Volumes/slapl01/Home/janderson/Source/ravenpack-dev/ 
> EconoRavenLisp/tests/float-tests.d64fsl"
> NIL
> NIL
> ? (load *)
> (TEST-SINGLE-HEAP 1.0 1000000) took 87 milliseconds (0.087 seconds) to run.
> Of that, 85 milliseconds (0.085 seconds) were spent in user mode
>         0 milliseconds (0.000 seconds) were spent in system mode
>         2 milliseconds (0.002 seconds) were spent executing other OS 
> processes.
> (TEST-SINGLE-STACK 1.0 1000000) took 55 milliseconds (0.055 seconds) to run.
> Of that, 53 milliseconds (0.053 seconds) were spent in user mode
>         0 milliseconds (0.000 seconds) were spent in system mode
>         2 milliseconds (0.002 seconds) were spent executing other OS 
> processes.
> (TEST-DOUBLE-HEAP 1.0D0 1000000) took 113 milliseconds (0.113 seconds) to 
> run.
> Of that, 62 milliseconds (0.062 seconds) were spent in user mode
>         26 milliseconds (0.026 seconds) were spent in system mode
>         25 milliseconds (0.025 seconds) were spent executing other OS 
> processes.
> 4 milliseconds (0.004 seconds) was spent in GC.
> 32,000,016 bytes of memory allocated.
> (TEST-DOUBLE-STACK 1.0D0 1000000) took 104 milliseconds (0.104 seconds) to 
> run.
> Of that, 40 milliseconds (0.040 seconds) were spent in user mode
>         23 milliseconds (0.023 seconds) were spent in system mode
>         41 milliseconds (0.041 seconds) were spent executing other OS 
> processes.
> 3 milliseconds (0.003 seconds) was spent in GC.
> 32,000,000 bytes of memory allocated.
> #P"/Volumes/slapl01/Home/janderson/Source/ravenpack-dev/ 
> EconoRavenLisp/tests/float-tests.d64fsl"
> ?
>
>



More information about the Openmcl-devel mailing list