Re: ForeignPtr performance

2007-12-17 Thread Simon Marlow

Bulat Ziganshin wrote:

Hello Scott,

Sunday, December 16, 2007, 11:57:33 PM, you wrote:


My question is: what exactly does GHC.Prim.touch# do? This appears to


it's a no-op (for ghc 6.6+ at least). its only task is to notify ghc
optimizer that data were accessed so it doesn't free the memory


Yes, exactly.  touch# generates no code, but it is vitally important 
because if the ForeignPtr is referencing data in the heap (like 
mallocForeignPtrBytes does), it prevents the data from being GC'd before 
the operation completes.


Cheers,
Simon
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re[2]: ForeignPtr performance

2007-12-17 Thread Bulat Ziganshin
Hello Simon,

Monday, December 17, 2007, 1:33:19 PM, you wrote:
 My question is: what exactly does GHC.Prim.touch# do? This appears to
 
 it's a no-op (for ghc 6.6+ at least). its only task is to notify ghc
 optimizer that data were accessed so it doesn't free the memory

 Yes, exactly.  touch# generates no code, but it is vitally important 
 because if the ForeignPtr is referencing data in the heap (like 
 mallocForeignPtrBytes does), it prevents the data from being GC'd before
 the operation completes.

a bit more details for Scott:

generated code is like this:

ptr - unsafeForeignPtrToPtr fptr
yourAction ptr
touch# fptr

without touch, the *last* action where fptr involved is its conversion
to ptr. GHC Runtime (not optimizer as i said) have no idea that ptr
and fptr is the same object, so after conversion it feels free to
dispose object pointed by fptr if GC occurs. this means that during
execution of your action data pointed by fptr/ptr may be suddenly
freed, allocated by other object, bang!

the touch pseudo-action is performed *after* your action and
references fptr again. so Runtime thinks there is one more usage of
fptr after yourAction and it doesn't dispose this chunk of memory if
GC occurs during your action

(unfortunately it's not mentioned anywhere on the Web)


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Re[2]: ForeignPtr performance

2007-12-17 Thread Scott Dillard
Thanks for the response guys.

I'm still curious as to the specific mechanism by which a strictly
compile-time function affects the run-time behavior of the GC. Bulat
says that touch# makes the runtime aware that the fptr object is still
in use, but how does it do this if, at runtime, it doesn't do
anything? Does if affect the scheduling of collections? Does it mark
the fptr object with some flag when its allocated? What if, for
example, if I put the touch# behind a branch that is conditional on
run-time values? How would this affect things?

I'm sure the answer to this is detailed and involves a lot of
specifics about GHC that I probably won't grasp, and maybe it isn't
appropriate for the whole list, but if there happens to be a short
answer, or there's a reference you can point me to, I'd appreciate it.

Thanks,
Scott



On Dec 17, 2007 4:12 AM, Bulat Ziganshin [EMAIL PROTECTED] wrote:
 Hello Simon,

 Monday, December 17, 2007, 1:33:19 PM, you wrote:
  My question is: what exactly does GHC.Prim.touch# do? This appears to
 
  it's a no-op (for ghc 6.6+ at least). its only task is to notify ghc
  optimizer that data were accessed so it doesn't free the memory

  Yes, exactly.  touch# generates no code, but it is vitally important
  because if the ForeignPtr is referencing data in the heap (like
  mallocForeignPtrBytes does), it prevents the data from being GC'd before
  the operation completes.

 a bit more details for Scott:

 generated code is like this:

 ptr - unsafeForeignPtrToPtr fptr
 yourAction ptr
 touch# fptr

 without touch, the *last* action where fptr involved is its conversion
 to ptr. GHC Runtime (not optimizer as i said) have no idea that ptr
 and fptr is the same object, so after conversion it feels free to
 dispose object pointed by fptr if GC occurs. this means that during
 execution of your action data pointed by fptr/ptr may be suddenly
 freed, allocated by other object, bang!

 the touch pseudo-action is performed *after* your action and
 references fptr again. so Runtime thinks there is one more usage of
 fptr after yourAction and it doesn't dispose this chunk of memory if
 GC occurs during your action

 (unfortunately it's not mentioned anywhere on the Web)



 --
 Best regards,
  Bulatmailto:[EMAIL PROTECTED]


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: ForeignPtr performance

2007-12-17 Thread Simon Marlow

Scott Dillard wrote:

Thanks for the response guys.

I'm still curious as to the specific mechanism by which a strictly
compile-time function affects the run-time behavior of the GC. Bulat
says that touch# makes the runtime aware that the fptr object is still
in use, but how does it do this if, at runtime, it doesn't do
anything? Does if affect the scheduling of collections? Does it mark
the fptr object with some flag when its allocated? What if, for
example, if I put the touch# behind a branch that is conditional on
run-time values? How would this affect things?


It's not as complicated as you think.  touch# takes a single argument, and 
does nothing with it; it's only purpose is to ensure that the value passed 
as its argument is alive as far as the rest of the compiler and runtime 
is concerned.


There's no special mechanism at work here: touch# is just like an ordinary 
IO operation, except that its implementation is empty, and the compiler 
cannot use this fact for optimisation purposes.  The compiler therefore 
arranges that the argument to touch# is available, just as it would for any 
other function.


Cheers,
Simon
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: ForeignPtr performance

2007-12-17 Thread Stefan O'Rear
On Mon, Dec 17, 2007 at 02:12:31PM +0300, Bulat Ziganshin wrote:
 Hello Simon,
 
 Monday, December 17, 2007, 1:33:19 PM, you wrote:
  My question is: what exactly does GHC.Prim.touch# do? This appears to
  
  it's a no-op (for ghc 6.6+ at least). its only task is to notify ghc
  optimizer that data were accessed so it doesn't free the memory
 
  Yes, exactly.  touch# generates no code, but it is vitally important 
  because if the ForeignPtr is referencing data in the heap (like 
  mallocForeignPtrBytes does), it prevents the data from being GC'd before
  the operation completes.
 
 a bit more details for Scott:
 
 generated code is like this:
 
 ptr - unsafeForeignPtrToPtr fptr
 yourAction ptr
 touch# fptr
 
 without touch, the *last* action where fptr involved is its conversion
 to ptr. GHC Runtime (not optimizer as i said) have no idea that ptr
 and fptr is the same object, so after conversion it feels free to
 dispose object pointed by fptr if GC occurs. this means that during
 execution of your action data pointed by fptr/ptr may be suddenly
 freed, allocated by other object, bang!

I'd like to elaborate that ptr, as far as the GC is concerned is *not a
pointer at all*, it is an integer memory address.  So it doesn't keep
anything alive, you need to hold on to fptr if you want the value to
exist.

Stefan


signature.asc
Description: Digital signature
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


ForeignPtr performance

2007-12-16 Thread Scott Dillard
Hi,

I do a lot of programming with small compound objects, things like 3d
vectors or RGBA tuples for images. For performance reasons, I keep
them in StorableArrays, since there is no way to use these things with
UArrays. (But that's a topic for another thread.)

Some how the notion got into my head that StorableArrays were slow, I
think from old versions of GHC. So I've gotten into the habit of using
withStorableArray and peek/poke to work on my arrays. This, as you can
imagine, is cumbersome. Not only because of the extra typing, but also
because I have to do everything in the IO monad, even if the array is
read-only.

So I'm thinking about writing my own IArray instance using ForeignPtr
for storage and unsafePerformIO for access. I did a little experiment,
comparing

 forM_ [0..lots] $ \i - withForeignPtr fp $ \p - pokeElemOff p i i

to

 withForeignPtr fp $ \p - forM_ [0..lots] $ \i - pokeElemOff p i i

And there seemed to be no difference in running time, which is great.
So I'm thinking of making unsafeAt something like

 unsafeAt (MyArray fp) i = unsafePerformIO $ withForeignPtr fp $ \p - 
 peekElemOff p i

My question is: what exactly does GHC.Prim.touch# do? This appears to
be the critical function of withForeignPtr, and if I write my IArray
instance as above, I have no way to float this touch# out of my loops,
as I currently do using withStorableArray. It appears from my simple
experiment that touch# does nothing at runtime. But maybe this is only
because no memory is allocated inside my simple loop? Maybe if I write
non-trivial loops, then touch# will actually cost something?

Intensely curious,
Scott
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: ForeignPtr performance

2007-12-16 Thread Bulat Ziganshin
Hello Scott,

Sunday, December 16, 2007, 11:57:33 PM, you wrote:

 My question is: what exactly does GHC.Prim.touch# do? This appears to

it's a no-op (for ghc 6.6+ at least). its only task is to notify ghc
optimizer that data were accessed so it doesn't free the memory


-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: ForeignPtr performance.

2004-07-19 Thread Simon Marlow
On 17 July 2004 05:31, John Meacham wrote:

 So, I was looking at the implementation of ForeignPtr's in an attempt
 to 
 determine why they were slow, and have an idea to speed them up..
 
 right now we have:
 
 ForeignPtr a
   = ForeignPtr ForeignObj# !(IORef [IO ()])
   | MallocPtr (MutableByteArray# RealWorld) !(IORef [IO ()])
 
 and I think the inderection caused by the disjunction is what is
 messing things up, not allowing ForeignPtrs to be inlined even in
 strict 
 contexts as the discriminator must still be examined. so how bout
 something like
 
 
 data ForeignPtr a = ForeignPtr Addr# !FP  -- note FP should be strict
 but BOXED [2] data FP = ForeignPtrObj ForeignObj# {-# UNPACK #-}
 !(IORef [IO ()]) | MallocPtr (MutableByteArray# RealWorld)
 {-# UNPACK #-} !(IORef [IO ()])

At first I thought this wasn't safe, but having thought about it some
more I now think it might be.  The reason it is safe is because all
ForeignPtr access happens inside withForeignPtr, which is ended by
touch#.  The implementation of touch# is invisible to the compiler, so
GHC's optimiser *must* ensure that the FP stays alive until the touch#,
and hence the ForeignObj# also stays alive.

Interestingly, unless I'm being stupid (entirely possible) this implies
that we don't actually need ForeignObj# at all!  This would do:

data FP = ForeignPtrObj {-# UNPACK #-} !(IORef [IO ()])
| MallocPtr (MutableByteArray# RealWorld)
{-# UNPACK #-} !(IORef [IO ()])

And in the ForeignPtrObj case, we place the finalizer on the IORef (we
need an atomic object with well-defined allocation semantics on which to
place the finalizer - just placing it on the FP wouldn't do).

Getting rid of ForeignObj# is a serious win.  Deleting code and
improving performance at the same time rarely happens these days!

Would you like to try this out?

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


ForeignPtr performance.

2004-07-16 Thread John Meacham
So, I was looking at the implementation of ForeignPtr's in an attempt to
determine why they were slow, and have an idea to speed them up..

right now we have:

ForeignPtr a 
  = ForeignPtr ForeignObj# !(IORef [IO ()])
  | MallocPtr (MutableByteArray# RealWorld) !(IORef [IO ()])  

and I think the inderection caused by the disjunction is what is
messing things up, not allowing ForeignPtrs to be inlined even in strict
contexts as the discriminator must still be examined. so how bout
something like


data ForeignPtr a = ForeignPtr Addr# !FP  -- note FP should be strict but BOXED [2] 
data FP = ForeignPtrObj ForeignObj# {-# UNPACK #-} !(IORef [IO ()])
| MallocPtr (MutableByteArray# RealWorld) {-# UNPACK #-} !(IORef [IO ()])  


by caching the frequently used Addr in a place where it may be unboxed
and hiding the details only needed when finalizing or garbage
collecting, I think we can bring ForeignPtrs up to the speed (if not
space) performance of plain old Ptr's.

John


[2] FP should be strict yet boxed so ForeignPtrs may be unboxed in
various places without duplicating the rarely used bookkeeping info.

hopefully 
touchForeignPtr (ForeignPtr _ fp) = 
IO $ \s - case touch# fp s of s - (# s, () #)
is good enough to keep things alive.
this is also why it is safe to UNPACK the IORefs in FP


-- 
John Meacham - repetae.netjohn 
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users