On 25/01/2011, at 20:57, Johan Tibell wrote: > On Tue, Jan 25, 2011 at 9:47 PM, Roman Leshchinskiy <[email protected]> > wrote: >> On 25/01/2011, at 20:26, Johan Tibell wrote: >> AFAIK, the GC never runs during foreign calls. This, combine with the fact >> that GHC can pass ByteArray# directly to FFI calls, should make memcpy safe >> even for unpinned byte arrays. At least that's how I understand it. > > I thought it did, but I might very well be misstaken. Perhaps Simon > could explain. Simon, is the GC allowed to run during "unsafe" foreign > calls? If no, should we be relying on this behavior?
My understanding is that the GC needs to "stop the world" before it can run. That is, all capabilities (i.e., hardware threads) have to synchronise, then the GC runs and then program execution resumes. This synchronisation can only happen on allocation; in particular, it can't happen inside a foreign call unless it calls back into Haskell. Simon, is that correct? >> GHC doesn't optimise tight loops very well at the moment. The LLVM backend >> helps a bit here but not as much as it could because LLVM doesn't like the >> code that we generate very much. > > Using a cloneArray# primop I can avoid the issue altogether in my > particular case. If we had a portable memset_pattern we could perhaps > speed up 'newArray#' in general. Yeah, a portable memset_pattern for things other than bytes would be very useful. Not only for newArray# but also for unboxed vectors of types other than Word8. >>>> It would be nice if those could be used on array slices. Maybe this: >>>> >>>> cloneArray# :: Array# a -> Int# -> Int# -> State# s -> Array# a >>>> cloneMutableArray# :: MutableArray# s a -> Int# -> Int# -> State# s -> (# >>>> State# s, MutableArray# s a #) >>>> freezeArray# :: MutableArray# s a -> Int# -> Int# -> State# s -> (# State# >>>> s, Array# a #) >>>> thawArray# :: Array# a -> Int# -> Int# -> State# s -> (# State# s, >>>> MutableArray# s a #) >>> >>> Supporting slicing would be nice. I'd prefer if we had e.g. >>> >>> cloneArray# :: Array# a -> Int# -> Int# -> State# s -> (# State# s >>> MutableArray# s a #) >>> >>> as you might won't to mutate the clone array before freezing it. The >>> use case I really want to support is updating a single array element, >>> which would entail first cloning the array, the writing an element, >>> and finally freezing the array. >>> >>>> Note that freezeArray# and thawArray# would be safe, i.e., would always >>>> copy. >>> >>> That sounds awfully expensive! >> >> I think your cloneArray# is the same as my thawArray#. I just tried to avoid >> having 4 different variants of clone. Or do you not want your cloneArray# to >> copy? > > I do want my cloneArray# to copy. I'm a bit confused however, did you > intend for both your cloneArray#, thawArray#, and freezeArray# to > copy? Put in another way, assuming that you start out with an Array# > that you want to update one element in and have another Array# in the > end, which sequence of primops (of the ones you defined) would you > use? thawArray# (which creates a mutable copy), update the element, then unsafeFreeze#. I thought that's what you wanted (modulo names). In theory, since both unsafeFreeze# and unsafeThaw# do some work we might want 4 different variants of clone: Array# -> Array# MutableArray# -> MutableArray# MutableArray# -> Array# Array# -> MutableArray# I just proposed to call the latter two thaw and freeze to avoid confusing names. I'm not sure if all of them are equally important, even though I would probably use all 4 in vector. Roman _______________________________________________ Cvs-ghc mailing list [email protected] http://www.haskell.org/mailman/listinfo/cvs-ghc
