[gambit-list] Re --enable-auto-forcing: Scope, how/where implemented, how build (with) it properly?

Adam adam.mlmb at gmail.com
Thu Jul 27 06:45:41 EDT 2017


I'll make closer benchmarking of auto forcing later, but, it incurs a quite
steep overhead. 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?


2017-06-16 13:52 GMT+08:00 Marc Feeley <feeley at iro.umontreal.ca>:

> Here is the definition of + from lib/_num.scm:
>
> (define-prim-nary (+ x y)
>   0
>   (if (##number? x) x '(1))
>   (##+ x y)
>   macro-force-vars
>   macro-no-check
>   (##pair? ##fail-check-number))
>
> The define-prim-nary macro will expand this to an n-ary procedure
> definition where the 0 argument case returns 0, the 1 argument case returns
> the argument if it is a number otherwise it raises a type error (by calling
> ##fail-check-number), and the general >= 2 argument case calls ##+ to fold
> the argument list. All arguments are passed to macro-force-vars to force
> the argument if it is a promise (and --enable-auto-forcing is used).
>
> Using set! to “short-circuit” promises is not a good idea because it
> introduces a cell for the variable (if local and not previously assigned)
> and this slows things down.  In early versions of Gambit (on Motorola 68K),
> the garbage collector did this short-circuiting (i.e. a reference to a
> promise was replaced with the value of the promise if it was previously
> forced).  This isn’t done currently but probably easy to add.
>
> Marc
>
>
>
> > On Jun 15, 2017, at 11:04 PM, Adam <adam.mlmb at gmail.com> wrote:
> >
> > 2017-06-13 5:30 GMT+07:00 Bradley Lucier <lucier at math.purdue.edu>:
> >
> > > On Jun 11, 2017, at 5:08 AM, Adam <adam.mlmb at gmail.com> wrote:
> > >
> > > Possibly the "macro-force-vars", which is used all over the runtime
> and compiler, would have something to do with this, but I don't find its
> definition anywhere.
> > >
> >
> > In _gambit#.scm:
> >
> > (macro-define-syntax macro-force-vars
> >   (lambda (stx)
> >     (syntax-case stx ()
> >       ((_ vars expr)
> >        (if (let* ((co
> >                    (##global-var-ref
> >                     (##make-global-var '##compilation-options)))
> >                   (comp-opts
> >                    (if (##unbound? co) '() co)))
> >              (assq 'force comp-opts))
> >
> >            (syntax-case (datum->syntax
> >                          #'vars
> >                          (map (lambda (x) `(,x (##force ,x)))
> >                               (syntax->list #'vars)))
> >                ()
> >              (bindings #'(let bindings expr)))
> >
> >            #'expr)))))
> >
> >
> > Ah right, https://github.com/gambit/gambit/blob/9c3dcbdc322a10673370c0
> 880696ba131144251d/lib/_gambit%23.scm#L316 , and used to be a
> define-macro, https://github.com/gambit/gambit/blob/29103e6a29b8fbbf7d6fc7
> 72a344b814be3f1c1a/lib/_gambit%23.scm#L492 , and all the rest of the code
> is meticulously padded with its use.
> >
> >
> > This also sheds a bit of light on why the slot containing the promise is
> not replaced with the forced value. Maybe that would be possible in some
> situations though.. When |x| is a symbol, it could be |set!| with the
> forced value?
> >
> > That would cover standard variable slots and not typedef, vector, pair
> etc. slots though, I guess I'd need to dig in a bit more to understand how
> this one actually works out. If you have any spontaneous ideas, feel free
> to share.
> >
> >
> > Any idea where in the sources fundamental primitives like |+| , |if| ,
> |or| autoforce?
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20170727/4c057dc3/attachment.htm>


More information about the Gambit-list mailing list