[gambit-list] Re --enable-auto-forcing: Scope, how/where implemented, how build (with) it properly?
adam.mlmb at gmail.com
Fri Sep 8 07:30:42 EDT 2017
Thank you very much for your clarification. Followup question below, to
really understand what you are saying.
2017-08-15 21:53 GMT+08:00 Marc Feeley <feeley at iro.umontreal.ca>:
> > 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!
I will provide it.
> > 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.
Can you please clarify what you mean here, by giving one or two pieces of
example code, that illustrate the difference between various code operation
options - so.. that would be
1) Interpreted code, vs.
2) Compiled code with (declare (safe)), vs.
3) Compiled code with (declare (not safe))
(I guess maybe (declare (block)) vs. (declare (separate)) could affect
forcing behavior, as inlined code not would be forced, but non-inlined code
In either case if I understand you right, there are examples where Gambit
with auto-forcing enabled, will fail executing ((delay (lambda ()
Also.. if I understand you right, there are cases when Gambit with
auto-forcing enabled also would fail evaluating (abs (delay 0)) .
Only for my clarity, please tell in what interval of conditions these will
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Gambit-list