[gambit-list] Re --enable-auto-forcing: Scope, how/where implemented, how build (with) it properly?
feeley at iro.umontreal.ca
Tue Aug 15 09:53:13 EDT 2017
> On Jul 27, 2017, at 6:45 AM, Adam <adam.mlmb at gmail.com> wrote:
> I'll make closer benchmarking of auto forcing later, but, it incurs a quite steep overhead.
Experimental data please!
> Meanwhile, I have a question:
> With --enable-auto-forcing, at procedure calls, that is (procedure 'arg1 'arg2 'etc.), |procedure| is forced, as we can see by the example that in both interpreted and compiled mode, ((delay (begin (println "Forced.") (lambda (v) v))) #t) evaluates (and it prints out "Forced.").
> I'd wildly guess that quite a lot of the overhead in auto-forcing is here. If you're sure the operator will never be a promise in any procedure call, then this particular aspect of auto forcing could be disabled.
> (Without checking, I would guess that while Gambit may optimize so that local procedure calls may avoid being brought through the |force| logics, then, this optimization would do so that calls to procedures defined in *other* modules such as the runtime, would *not* be taken through |force| also. That should be positive for speed.)
> Would it be possible for me to disable this particular aspect of the auto-forcing, to get higher performance?
Currently auto-forcing only works in interpreted code. So if your program does (f x) and (car y) and you compile that, then “f” will not be forced and “y” will not be forced if car is inlined, for example if you (declare (not safe)). You can consider this a bug… to be fixed.
However, compiled predefined functions do the auto-forcing (when the system is configured with --enable-auto-forcing). So (car y) will force y if the actual function is called, for example if you (declare (safe)), which is the default.
Note that for “safe” compiled code, when compiling (f x) where f is a mutable global variable, it is necessary to generate a check that f is a procedure. If it is not a procedure a handler is called that normally raises an exception. This handler could easily be extended to first force the value and check if the resulting value is a procedure and proceed with the call if it is (hooray for raising exceptions in tail-position!). So there would be no additional cost for safe compiled code.
More information about the Gambit-list