[MLton-user] defunctorize limit?

Sean McLaughlin seanmcl at gmail.com
Mon Dec 10 11:28:08 PST 2007


Hello,

  I'm experiencing some unexpected behavior.  I have a number of
functors parameterized by
an abstract arithmetic signature.  For most of my code, when these
functors are instantiated to
Real.real type, they run as fast as a version without the abstraction.
 However, I found an
example that runs over 10X slower with the abstraction than without.
That is, when I
inline a monomorphic function at type real, it runs 10X faster than
when I instantiate
a functor with the exact same function body.  So far I have been
unable to construct
a small example that exhibits this behavior.  I was thus wondering if
there is a limit
to the amount of defunctorization being done.  If so, perhaps there is
a command line
argument I could increase.

Thanks,

Sean

Code fragment:


functor FocusFun(A : ARITH)
struct

  open A

  fun focus_up (xs as (lo,hi),(d_lo,d_hi)) =
      if d_hi <= zero then (lo,lo)
      else if d_lo >= zero then (hi,hi)
      else xs

  fun focus_down (xs as (lo,hi),(d_lo,d_hi)) =
      if d_hi <= zero then (hi,hi)
      else if d_lo >= zero then (lo,lo)
      else xs

end

functor Diff2Functions6PosFun(...
                                            structure DD6 :
INTERVAL_DIFF2 where type ...
                                                             (*
setting rounding modes only make sense for real endpoints*)
                                                             where
type I.A.elem = real)
        :> OPTIMIZABLE_FUNCTIONS where type A.elem = DD6.elem =
struct

structure C = FocusFun(I)


(* If I uncomment this section
  (a copy of the code from FocusFun)
   and comment the current defs of focus* it type checks because I specify
   that the input structure must have an embedded real type, and
delta_x runs 10X faster.  *)

(*
  fun focus_up (xs as (lo,hi),(d_lo,d_hi)) =
      if d_hi <= 0.0 then (lo,lo)
      else if d_lo >= 0.0 then (hi,hi)
      else xs

  fun focus_down (xs as (lo,hi),(d_lo,d_hi)) =
      if d_hi <= 0.0 then (hi,hi)
      else if d_lo >= 0.0 then (lo,lo)
      else xs
*)
  val focus_up = C.focus_up
  val focus_down = C.focus_down


fun delta_x xs =
   let
        ...

        val ((x1_lo,x1_hi),(x2_lo,x2_hi),(x3_lo,x3_hi),
             (x4_lo,x4_hi),(x5_lo,x5_hi),(x6_lo,x6_hi)) =
            T6.map2 focus_up (xs,dd1)

        val d1_hi = ~ 2.0*x1_lo*x4_lo + x2_hi*x4_hi + x3_hi*x4_hi -
x4_lo*x4_lo +
                    x2_hi*x5_hi - x3_lo*x5_lo + x4_hi*x5_hi - x2_lo*x6_lo +
                    x3_hi * x6_hi + x4_hi*x6_hi
         ...

        (* repeat the variable shadowing 12 times, thus around 12 * 6
calls to focus *)

        val v_hi = ~x2_lo*x3_lo*x4_lo - x1_lo*x3_lo*x5_lo - x1_lo*x2_lo*x6_lo
                   - x4_lo*x5_lo*x6_lo
                   + x3_hi*x6_hi*(x1_hi + x2_hi + x4_hi + x5_hi)
                   - x3_lo*x6_lo*(x3_lo + x6_lo)
                   + x2_hi*x5_hi*(x1_hi + x3_hi + x4_hi + x6_hi)
                   - x2_lo*x5_lo*(x2_lo + x5_lo)
                   + x1_hi*x4_hi*(x2_hi + x3_hi + x5_hi + x6_hi)
                   - x1_lo*x4_lo*(x1_lo + x4_lo)

  in
    ...
  end



More information about the MLton-user mailing list