From: Eugene K. <eki...@gm...> - 2011-11-02 14:05:49
|
Hm, it seems then that another correct solution would be to {-# INLINE #-} cFloatConv - it would get transformed to realToFrac everywhere, and GHC would specialize it. I'm now trying to check this, but somehow my ghc-pkg broke and I'm now going to spend the next eternity recompiling gtk2hs from scratch with enabled split-objs and enabled library-profiling, if you know what I mean... I'll report back when I get any results. On Wed, Nov 2, 2011 at 4:00 PM, <wag...@se...> wrote: > If the problem really is that cFloatConv is using the generic > fromRational . toRational implementation, then the correct solution is > to simply _not define cFloatConv_ and use realToFrac everywhere. GHC > already has tons of specialization rules for realToFrac. However, > rewrite rules (which are what is generated by a specialization) are > only syntactic. This, combined with the NOINLINE pragma you have on > cFloatConv, means that they are never allowed to fire. > > ~d > > Quoting Eugene Kirpichov <eki...@gm...>: > > > Sorry for re-sending, my previous attempt got ignored by gtk2hs-devel > > mailing list as I wasn't subscribed. Now I am. > > > > On Wed, Nov 2, 2011 at 3:14 PM, Eugene Kirpichov <eki...@gm... > >wrote: > > > >> Yay!!! > >> > >> I made a small change in Types.chs and got my original > cairo-binding-based > >> program to be just as blazing fast. The only problem I have with this is > >> that I used multiparameter type classes. > >> > >> Dear gtk2hs team! Is it possible to incorporate my changes? I'm pretty > >> sure people will be happy by an order-of-magnitude speedup. Probably the > >> stuff could be wrapped in #define's for those who aren't using GHC and > >> can't use multiparameter type classes? > >> > >> I am pretty sure I could have done the same with rewrite rules, but I > >> tried for a while and to no avail. > >> > >> FAILED SOLUTION: rewrite rules > >> cFloatConv :: (RealFloat a, RealFloat b) => a -> b > >> cFloatConv = realToFrac > >> {-# NOINLINE cFloatConv #-} > >> {-# RULES "cFloatConv/float2Double" cFloatConv = float2Double #-} > >> {-# RULES "cFloatConv/double2Float" cFloatConv = double2Float #-} > >> {-# RULES "cFloatConv/self" cFloatConv = id #-} > >> > >> For some reason, the rules don't fire. Anyone got an idea why? > >> > >> SUCCEEDED SOLUTION: multiparameter type classes > >> > >> I rewrote cFloatConv like this: > >> > >> import GHC.Float > >> class (RealFloat a, RealFloat b) => CFloatConv a b where > >> cFloatConv :: a -> b > >> cFloatConv = realToFrac > >> > >> instance CFloatConv Double Double where cFloatConv = id > >> instance CFloatConv Double CDouble > >> instance CFloatConv CDouble Double > >> instance CFloatConv Float Float where cFloatConv = id > >> instance CFloatConv Float Double where cFloatConv = float2Double > >> instance CFloatConv Double Float where cFloatConv = double2Float > >> > >> and replaced a couple of constraints in functions below by usage of > >> CFloatConv. > >> > >> > >> On Wed, Nov 2, 2011 at 2:25 PM, Felipe Almeida Lessa < > >> fel...@gm...> wrote: > >> > >>> +gtk2hs-devel > >>> > >>> On Wed, Nov 2, 2011 at 8:15 AM, Eugene Kirpichov <eki...@gm... > > > >>> wrote: > >>> > Any idea how to debug why all the GMP calls? > >>> > I'm looking at even the auto-generated source for cairo bindings, > but I > >>> > don't see anything at all that could lead to *thousands* of them. > >>> > >>> Found them. Look at the Types module and you'll see > >>> > >>> cFloatConv :: (RealFloat a, RealFloat b) => a -> b > >>> cFloatConv = realToFrac > >>> > >>> This function (or its cousins peekFloatConv, withFloatConv...) are > >>> used *everywhere*. > >>> > >>> Looking at this module with ghc-core we see that GHC compiled a > >>> generic version of cFloatConv: > >>> > >>> Graphics.Rendering.Cairo.Types.$wcFloatConv > >>> :: forall a_a3TN b_a3TO. > >>> (RealFloat a_a3TN, RealFrac b_a3TO) => > >>> a_a3TN -> b_a3TO > >>> [GblId, > >>> Arity=3, > >>> > >>> Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=3, Value=True, > >>> ConLike=True, Cheap=True, Expandable=True, > >>> Guidance=IF_ARGS [3 3 0] 12 0}] > >>> Graphics.Rendering.Cairo.Types.$wcFloatConv = > >>> \ (@ a_a3TN) > >>> (@ b_a3TO) > >>> (w_s5zg :: RealFloat a_a3TN) > >>> (ww_s5zj :: RealFrac b_a3TO) > >>> (w1_s5zA :: a_a3TN) -> > >>> fromRational > >>> @ b_a3TO > >>> ($p2RealFrac @ b_a3TO ww_s5zj) > >>> (toRational > >>> @ a_a3TN > >>> ($p1RealFrac > >>> @ a_a3TN ($p1RealFloat @ a_a3TN w_s5zg)) > >>> w1_s5zA) > >>> > >>> Note that this is basically cFloatConv = fromRational . toRational. > >>> > >>> *However*, GHC also compiled a Double -> Double specialization: > >>> > >>> Graphics.Rendering.Cairo.Types.cFloatConv1 > >>> :: Double -> Double > >>> [GblId, > >>> Arity=1, > >>> > >>> Unf=Unf{Src=InlineStable, TopLvl=True, Arity=1, Value=True, > >>> ConLike=True, Cheap=True, Expandable=True, > >>> Guidance=ALWAYS_IF(unsat_ok=True,boring_ok=False) > >>> Tmpl= \ (eta_B1 [Occ=Once!] :: Double) -> > >>> case eta_B1 of _ { D# ww_a5v3 [Occ=Once] -> > >>> case $w$ctoRational ww_a5v3 > >>> of _ { (# ww2_a5v8 [Occ=Once], ww3_a5v9 [Occ=Once] #) > -> > >>> $wfromRat ww2_a5v8 ww3_a5v9 > >>> } > >>> }}] > >>> Graphics.Rendering.Cairo.Types.cFloatConv1 = > >>> \ (eta_B1 :: Double) -> > >>> case eta_B1 of _ { D# ww_a5v3 -> > >>> case $w$ctoRational ww_a5v3 > >>> of _ { (# ww2_a5v8, ww3_a5v9 #) -> > >>> $wfromRat ww2_a5v8 ww3_a5v9 > >>> } > >>> } > >>> > >>> ...which is also equivalent to fromRational . toRational however with > >>> the type class inlined! Oh, god... > >>> > >>> Cheers, > >>> > >>> -- > >>> Felipe. > >>> > >>> _______________________________________________ > >>> Haskell-Cafe mailing list > >>> Has...@ha... > >>> http://www.haskell.org/mailman/listinfo/haskell-cafe > >>> > >> > >> > >> > >> -- > >> Eugene Kirpichov > >> Principal Engineer, Mirantis Inc. http://www.mirantis.com/ > >> Editor, http://fprog.ru/ > >> > > > > > > > > -- > > Eugene Kirpichov > > Principal Engineer, Mirantis Inc. http://www.mirantis.com/ > > Editor, http://fprog.ru/ > > > > > > > ------------------------------------------------------------------------------ > RSA® Conference 2012 > Save $700 by Nov 18 > Register now! > http://p.sf.net/sfu/rsa-sfdev2dev1 > _______________________________________________ > Gtk2hs-devel mailing list > Gtk...@li... > https://lists.sourceforge.net/lists/listinfo/gtk2hs-devel > -- Eugene Kirpichov Principal Engineer, Mirantis Inc. http://www.mirantis.com/ Editor, http://fprog.ru/ |