From: Eugene K. <eki...@gm...> - 2011-11-02 11:19:35
|
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/ |
From: <wag...@se...> - 2011-11-02 12:00:30
|
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/ > |
From: Axel S. <Axe...@in...> - 2011-11-02 12:52:24
|
This is very interesting. There was an issue about ultra slow Cairo output on Mac OS which was due to a bug in cairo. So I thought this slowness thing is yet another instance of this. The fact that it has to do with Double to CDouble conversation via GMP Integers is something we should definitely avoid. Even if this is fixed in GHC, I'd be more than happy to use a specialized function in our cairo binding. Axel. On 02.11.2011, at 13:00, 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 |
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/ |
From: Eugene K. <eki...@gm...> - 2011-11-02 14:03:36
|
Hi, No, I didn't, as I read in the GHC docs that it is deprecated in favor of the RULES pragma (I wanted to replace specifically with floatToDouble and doubleToFloat). On Wed, Nov 2, 2011 at 5:24 PM, Jean-Marie Gaillourdet <jm...@ga...>wrote: > Hi Eugene, > > did you try using the SPECIALIZE pragma? It is part of the Haskell 98 and > Haskell 2010 specifications. > > On 02.11.2011, at 12:14, Eugene Kirpichov 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 #-} > > > See [1] in GHC User Guide. > > cFloatConv :: (RealFloat a, RealFloat b) => a -> b > cFloatConv = realToFrac -- or try fromRational . toRational > > {-# SPECIALIZE cFloatConv :: Float -> Double #-} > {-# SPECIALIZE cFloatConv :: Double -> Float #-} > > I did not try to compile or even benchmark this code. But I think it might > help in your case. > > Cheers, > Jean > > [1]: > http://www.haskell.org/ghc/docs/latest/html/users_guide/pragmas.html#specialize-pragma -- Eugene Kirpichov Principal Engineer, Mirantis Inc. http://www.mirantis.com/ Editor, http://fprog.ru/ |
From: Eugene K. <eki...@gm...> - 2011-11-02 16:34:21
|
Heh. Guess what! A simple {-# INLINE cFloatConv #-} helped to the same extent! Axel, I think this change should be pretty easy to incorporate, and it probably makes sense to inline all other functions in Types.chs too. Would you like me to send the trivial darcs patch or the gtk2hs team will take care of this? On Wed, Nov 2, 2011 at 7:29 PM, Felipe Almeida Lessa <fel...@gm...> wrote: > On Wed, Nov 2, 2011 at 11:24 AM, Jean-Marie Gaillourdet > <jm...@ga...> wrote: >> Hi Eugene, >> >> did you try using the SPECIALIZE pragma? It is part of the Haskell 98 and Haskell 2010 specifications. > > I don't think it's going to make any difference, as the core already > have an specialized poor version. See my first e-mail. > > -- > Felipe. > -- Eugene Kirpichov Principal Engineer, Mirantis Inc. http://www.mirantis.com/ Editor, http://fprog.ru/ |
From: Eugene K. <eki...@gm...> - 2011-11-03 04:03:17
|
Thanks! I'll definitely consider your library in the future, but for now, as we can see, there's no necessity in rewriting cFloatConv at all - {-# INLINE #-} suffices :) On Thu, Nov 3, 2011 at 3:30 AM, wren ng thornton <wr...@fr...> wrote: > On 11/2/11 7:14 AM, Eugene Kirpichov wrote: > >> 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 >> > > If you're going the MPTC route, I suggest you use logfloat:Data.Number.**RealToFrac[1]. > I don't have the CDouble and CFloat instances, but I could add them. The > instances themselves are only moderately more clever than yours ---namely > using CPP for portability to non-GHC compilers--- but I think it's good for > people to rally around one implementation of the solution instead of having > a bunch of copies of the same thing, each poorly maintained because of the > distributedness. > > > [1] http://hackage.haskell.org/**packages/archive/logfloat/0.** > 12.1/doc/html/Data-Number-**RealToFrac.html<http://hackage.haskell.org/packages/archive/logfloat/0.12.1/doc/html/Data-Number-RealToFrac.html> > > -- > Live well, > ~wren > > > ______________________________**_________________ > Haskell-Cafe mailing list > Has...@ha... > http://www.haskell.org/**mailman/listinfo/haskell-cafe<http://www.haskell.org/mailman/listinfo/haskell-cafe> > -- Eugene Kirpichov Principal Engineer, Mirantis Inc. http://www.mirantis.com/ Editor, http://fprog.ru/ |
From: Axel S. <Axe...@in...> - 2011-11-03 07:41:43
|
Hi Eugene, On 02.11.2011, at 17:34, Eugene Kirpichov wrote: > Heh. > > Guess what! > A simple {-# INLINE cFloatConv #-} helped to the same extent! > > Axel, I think this change should be pretty easy to incorporate, and it > probably makes sense to inline all other functions in Types.chs too. > I've added INLINE pragmas to all these odd c2hs marshalling functions. Could you pull and check if I've done it correctly? Thanks for tracking this down! Axel > Would you like me to send the trivial darcs patch or the gtk2hs team > will take care of this? > > On Wed, Nov 2, 2011 at 7:29 PM, Felipe Almeida Lessa > <fel...@gm...> wrote: >> On Wed, Nov 2, 2011 at 11:24 AM, Jean-Marie Gaillourdet >> <jm...@ga...> wrote: >>> Hi Eugene, >>> >>> did you try using the SPECIALIZE pragma? It is part of the Haskell >>> 98 and Haskell 2010 specifications. >> >> I don't think it's going to make any difference, as the core already >> have an specialized poor version. See my first e-mail. >> >> -- >> Felipe. >> > > > > -- > Eugene Kirpichov > Principal Engineer, Mirantis Inc. http://www.mirantis.com/ > Editor, http://fprog.ru/ |
From: Eugene K. <eki...@gm...> - 2011-11-03 09:02:20
|
Hi, The actual thanks for tracking this down go to Vincent Hanquez for finding that we're doing a lot of gmp calls (and for making me aware of ltrace), and to Felipe Lessa for finding that this is caused by poor code generated for cFloatConv :) Your changes look identical to those that I made in my copy. On Thu, Nov 3, 2011 at 11:41 AM, Axel Simon <Axe...@in...> wrote: > Hi Eugene, > > > On 02.11.2011, at 17:34, Eugene Kirpichov wrote: > > Heh. >> >> Guess what! >> A simple {-# INLINE cFloatConv #-} helped to the same extent! >> >> Axel, I think this change should be pretty easy to incorporate, and it >> probably makes sense to inline all other functions in Types.chs too. >> >> > I've added INLINE pragmas to all these odd c2hs marshalling functions. > Could you pull and check if I've done it correctly? > > Thanks for tracking this down! > > Axel > > > Would you like me to send the trivial darcs patch or the gtk2hs team >> will take care of this? >> >> On Wed, Nov 2, 2011 at 7:29 PM, Felipe Almeida Lessa >> <fel...@gm...> wrote: >> >>> On Wed, Nov 2, 2011 at 11:24 AM, Jean-Marie Gaillourdet >>> <jm...@ga...> wrote: >>> >>>> Hi Eugene, >>>> >>>> did you try using the SPECIALIZE pragma? It is part of the Haskell 98 >>>> and Haskell 2010 specifications. >>>> >>> >>> I don't think it's going to make any difference, as the core already >>> have an specialized poor version. See my first e-mail. >>> >>> -- >>> Felipe. >>> >>> >> >> >> -- >> 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/ |
From: Eugene K. <eki...@gm...> - 2011-11-11 14:51:54
|
Hi Axel, When do you expect to publish an updated version of gtk2hs on hackage? On Thu, Nov 3, 2011 at 1:02 PM, Eugene Kirpichov <eki...@gm...> wrote: > Hi, > The actual thanks for tracking this down go to Vincent Hanquez for finding > that we're doing a lot of gmp calls (and for making me aware of ltrace), and > to Felipe Lessa for finding that this is caused by poor code generated for > cFloatConv :) > Your changes look identical to those that I made in my copy. > On Thu, Nov 3, 2011 at 11:41 AM, Axel Simon <Axe...@in...> wrote: >> >> Hi Eugene, >> >> On 02.11.2011, at 17:34, Eugene Kirpichov wrote: >> >>> Heh. >>> >>> Guess what! >>> A simple {-# INLINE cFloatConv #-} helped to the same extent! >>> >>> Axel, I think this change should be pretty easy to incorporate, and it >>> probably makes sense to inline all other functions in Types.chs too. >>> >> >> I've added INLINE pragmas to all these odd c2hs marshalling functions. >> Could you pull and check if I've done it correctly? >> >> Thanks for tracking this down! >> >> Axel >> >>> Would you like me to send the trivial darcs patch or the gtk2hs team >>> will take care of this? >>> >>> On Wed, Nov 2, 2011 at 7:29 PM, Felipe Almeida Lessa >>> <fel...@gm...> wrote: >>>> >>>> On Wed, Nov 2, 2011 at 11:24 AM, Jean-Marie Gaillourdet >>>> <jm...@ga...> wrote: >>>>> >>>>> Hi Eugene, >>>>> >>>>> did you try using the SPECIALIZE pragma? It is part of the Haskell 98 >>>>> and Haskell 2010 specifications. >>>> >>>> I don't think it's going to make any difference, as the core already >>>> have an specialized poor version. See my first e-mail. >>>> >>>> -- >>>> Felipe. >>>> >>> >>> >>> >>> -- >>> 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/ > -- Eugene Kirpichov Principal Engineer, Mirantis Inc. http://www.mirantis.com/ Editor, http://fprog.ru/ |