Scott Dillard | 12 Dec 19:01

newtypes and optimization

Hi,

I have a statically-sized-list library that I use for linear algebra stuff.
It's got a vector type something like this:

> data V a b = V a b

so that a 3D vector is

> type Vec3 a = V a (V a (V a ()))

and I have type classes for operations on these things, like so:

> class VZipWith a b c u v w | {-lots of fundeps-} where
>   vzipWith :: (a -> b -> c) -> u -> v -> w
>
> instance VZipWith a b c (V a ()) (V b ()) (V c ()) where
>   vzipWith f (V x ()) (V y ()) = V (f x y) ()
>
> instance
>   VZipWith a b c (V a u) (V b v) (V c w)
>   => VZipWith a b c (V a (V a u)) (V b (V b v)) (V c (V c w))
>     where
>       vzipWith f (V x u) (V y v) = V (f x y) (vzipWith f u v)

so that vector addition is

> vadd = vzipWith (+)

I put strictness annotations and INLINE pragmas all over the place, and GHC
(Continue reading)

Stefan O'Rear | 12 Dec 21:41

Re: newtypes and optimization

On Wed, Dec 12, 2007 at 11:02:15AM -0700, Scott Dillard wrote:
> with strictness annotations and INLINEs for everything. I also tried automatic
> newtype deriving, with no luck. Why does a newtype defeat so much of the
> optimization?
> 
> Thanks,
> Scott

(Not a GHC developer, but someone fairly familiar with how the Simons
work)

What version of GHC are you using?  The implementation of newtypes was
completely redone in the 6.7.x period.

Do you have a fairly small complete working example?  If so, link to or
attach a tarball - will make their jobs much easier.

Stefan
_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users <at> haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Don Stewart | 12 Dec 21:48
Gravatar

Re: newtypes and optimization

stefanor:
> On Wed, Dec 12, 2007 at 11:02:15AM -0700, Scott Dillard wrote:
> > with strictness annotations and INLINEs for everything. I also tried automatic
> > newtype deriving, with no luck. Why does a newtype defeat so much of the
> > optimization?
> > 
> > Thanks,
> > Scott
> 
> (Not a GHC developer, but someone fairly familiar with how the Simons
> work)
> 
> What version of GHC are you using?  The implementation of newtypes was
> completely redone in the 6.7.x period.
> 
> Do you have a fairly small complete working example?  If so, link to or
> attach a tarball - will make their jobs much easier.
> 
> Stefan

Yeah, this sounds like maybe a bug, or maybe something wrong. We need to
investigate! An example please.

-- Don
Scott Dillard | 12 Dec 22:18

Re: newtypes and optimization

You can find an example at:

graphics.cs.ucdavis.edu/~sdillard/newtype-maybe-bug.tar.gz

Here's my session with it:

ghc --make -O2 -DFAST Test
time ./Test +RTS -tstderr

<<ghc: 21120 bytes, 2 GCs, 32768/32768 avg/max bytes residency (1
samples), 1M in use, 0.00 INIT (0.00 elapsed), 7.52 MUT (8.70
elapsed), 0.00 GC (0.00 elapsed) :ghc>>

real	0m8.827s
user	0m7.520s
sys	0m1.224s

ghc --make -O2 -DSLOW Test -no-recomp
time ./Test +RTS -tstderr

<Ctrl-C>

Test: interrupted
<<ghc: 13476104656 bytes, 25762 GCs, 36864/36864 avg/max bytes
residency (1 samples), 1M in use, 0.00 INIT (0.00 elapsed), 91.19 MUT
(92.85 elapsed), 0.22 GC (0.36 elapsed) :ghc>>

real	1m33.232s
user	1m31.410s
sys	0m1.020s
(Continue reading)

Simon Peyton-Jones | 13 Dec 11:31

RE: newtypes and optimization

| However when I do this:
|
| > newtype Quaternion = Q (Vec4 Double)
|
| Everything is ruined. Functions like peek and vadd are no longer inlined,
| intermediate linked lists are created all over the place. The Quaternion
| Storable instance looks like this

Turns out this is a perf bug in 6.8 that I fixed a couple of weeks ago in the HEAD, but didn't merge. 
(Implication constraints aren't getting INLINE pragmas.)

With the HEAD we get this, which should make you happy.  The HEAD allocates only 9kbytes in both -DSLOW and
-DFAST, whereas 6.8 allocates 21kbytes in -DFAST (and off the map for -DSLOW).

I guess we should get this patch into the 6.8 branch.

Simon

$gpj --make -O2 -DFAST Test -o Test-fast
[1 of 2] Compiling VecMath          ( VecMath.hs, VecMath.o )
NOTE: Simplifier still going after 4 iterations; bailing out.  Size = 7311
[2 of 2] Compiling Main             ( Test.hs, Test.o )
Linking Test-fast ...
bash-3.1$ rm -f *.o
bash-3.1$ $gpj --make -O2 -DSLOW Test -o Test-slow
[1 of 2] Compiling VecMath          ( VecMath.hs, VecMath.o )
NOTE: Simplifier still going after 4 iterations; bailing out.  Size = 7311
[2 of 2] Compiling Main             ( Test.hs, Test.o )
Linking Test-slow ...
bash-3.1$ time ./Test-fast +RTS -sstderr
(Continue reading)


Gmane