[plt-dev] unchecked unsafe operations (was Release Announcement for v4.2.3, third call)

From: Doug Williams (m.douglas.williams at gmail.com)
Date: Sun Dec 13 14:45:31 EST 2009

Thanks for the update, Matthew. I am currently getting Version 4.0 of the
Science Collection ready to release in the next few weeks. It will require
PLT Scheme 4.2.3 or later. As I said earlier, I am using unsafe operations
extensively in the implementation of the Chebyshev approximation routines
(used to implement many of the special functions), the ordinary differential
equation (ODE) solvers (also used by the Simulation Collection for
continuous models), and the statistics routines.

I am attempting to ensure that even when using the unchecked versions of the
routines (that bypass the contract checks) there are no instances where the
routines crash. Basically, I have a couple of macros that I used to ensure
reals are floats and integers are fixnums before using the unsafe operations
and raise an exception if they cannot be coerced. There is obviously some
overhead in doing this, but in most cases I think it is unschemely to
require floats for all reals input to the routines. [There aren't that many
occasions where I use unsafe fixnums except in cases where I know they are
vector indices.] This isn't a problem with the Chebyshev and ODE solvers
where I control the internal state and can make sure that all of the state
variables are indeed floats.

I guess the point of this message is to say I will use the unsafe operations
to implement (some of) the computationally intensive procedures, but attempt
to ensure that the resulting routines are not themselves 'unsafe' (in the
sense of crashing when given 'bad' data).

I can make the routines available for testing by interested parties prior to
releasing them to PLaneT. This would also allow you to critique the unsafe
constructs and see if you have any suggestions for improving my use of them.


On Sun, Dec 13, 2009 at 11:46 AM, Matthew Flatt <mflatt at cs.utah.edu> wrote:

> At Fri, 4 Dec 2009 17:49:45 -0700, Doug Williams wrote:
> > I have updated several of the more computationally expensive components
> of
> > the science collection [...] to use the new unsafe operations. [...]
> >
> > The question is to what extent you guys as the development team still
> > consider these as experimental features.
> We previously defined "experimental" as
>  I think of it as an experiment in that I'm not sure that this is the
>  right approach for better performance. But it seems worth a try, and
>  if it works well for many purposes, then it'll stick.
> It sounds like the unchecked--unsafe operations are working for you, we
> have found other uses in parallel algorithms, and they seem to be
> working out in general. So, it's going to stick.
> As of yesterday, the bytecode compiler can now improve the chances for
> unboxed flonums in the JIT. For example, the bytecode compiler
> effectively converts
>  (let ([y (unsafe-fl+ c d)]
>       [x (unsafe-fl+ a b)])
>   (unsafe-fl+ x (unsafe-fl+ y (unsafe-fx->fl (+ q v)))))
> to
>  (let ([q+v (+ q v)])
>   (unsafe-fl+ (unsafe-fl+ a b)
>               (unsafe-fl+ (unsafe-fl+ c d)
>                           (unsafe-fx->fl q+v))
> so that all the JIT sees all the `unsafe-fl' operations together.
> The bytecode compiler can push `let'-bound flonum-producing expressions
> into other flonum operations only when the corresponding binding is
> used just once. Also, the compiler must be able to tell that the move
> doesn't reorder the expression relative to an observable effect. For
> example, if you insert a `printf' before the body the of `let' above,
> then the `let' bindings are not moved down. I might improve the
> transformation to consider specific dependencies, instead of giving up
> on all observable effects (e.g., `printf' definitely won't affect the
> values of `a' through `d' if none of them are mutable). Already,
> though, a potential crash from an unsafe operation, doesn't count for
> moving other expressions; for example, the right-hand sides of the `y'
> and `x' bindings are reordered above, on the grounds that you cannot
> reliably detect an crashes that might happen as a side effect.
> The transformation to pull non-flonum expressions out of an `unsafe-fl'
> argument position is less constrained. Multiple arguments always can be
> lifted to fresh `let' bindings without changing the order of the
> expressions. And since potential crashes from unsafe operations don't
> count, nested unsafe operations can be kept as immediate arguments
> without concern for argument order.
> Two main weaknesses remain:
>  * It's not so easy to tell when the compiler will be able to avoid
>   boxing. The `mzc --decompile' tool now adds `#%flonum' annotations
>   on decompiled code to help you double-check, but that's not a great
>   help when writing programs in the first place.
>  * Flonum results that are used more than once (such as a `let' binding
>   of an identifier that is used in two places) are not yet handled by
>   the JIT. Adding some form of stack-based local storage, instead of
>   always boxing in the heap, is the next step. That change will also
>   simplify the rules about when intermediate flonums are unboxed.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20091213/9dcf19fb/attachment.html>

Posted on the dev mailing list.