On Tue, Jan 25, 2011 at 9:47 PM, Roman Leshchinskiy <r...@cse.unsw.edu.au> 
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?

>> I also want to avoid to
>> avoid filling the array twice (first with a initial element I don't
>> care about, followed by the elements of another array).
>
> That only applies to Array#, not ByteArray#, right? I fully agree that having 
> block copy primops for the former is very worthwhile. I'm not sure we need 
> primops for the latter.

Right, that only applies to Array#. I also agree we should avoid
unnecessary primops.

>
>> In addition, I'd like to avoid unnecessarily filling the arrays with a
>> default element just to overwrite them right after. Speaking of array
>> initialization, I'm not sure the CMM compiler is up to optimizing the
>> initialization loop well either. My understanding is that the CMM
>> compiler is not as strong as e.g. GCC when it comes to optimizing
>> loops.
>
> 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.

>>> 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?

Johan

_______________________________________________
Cvs-ghc mailing list
Cvs-ghc@haskell.org
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to