Opened 2 years ago

Last modified 17 hours ago

#11143 new feature request

Feature request: Add index/read/write primops with byte offset for ByteArray#

Reported by: vagarenko Owned by:
Priority: normal Milestone:
Component: Compiler Version: 7.10.2
Keywords: newcomers Cc: sjakobi
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Runtime performance bug Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

Currently, primops for indexing ByteArray# and reading/writing MutableByteArray# have the following form:

indexTYPEArray# :: ByteArray#          -> Int# -> TYPE#
readTYPEArray#  :: MutableByteArray# s -> Int# -> State# s -> (#State# s, TYPE##)
writeTYPEArray# :: MutableByteArray# s -> Int# -> TYPE# -> State# s -> State# s

where second argument of type Int# is an offset measured in terms of the size of TYPE#.

This is inconvinient if I want to store values of different types inside ByteArray#: I have to read values of type Int8 and then glue them together with some bitwise operations.

I suggest adding number of primops, similar to existing ones, which would accept offset in bytes from the start of the ByteArray#:

-- | Read 8-bit integer; offset in bytes.
indexByteInt8Array#  :: ByteArray# -> Int# -> Int#

-- | Read 16-bit integer; offset in bytes.
indexByteInt16Array# :: ByteArray# -> Int# -> Int#

-- | Read 32-bit integer; offset in bytes.
indexByteInt32Array# :: ByteArray# -> Int# -> Int#

-- | Read 8-bit integer; offset in bytes.
readInt8Array#  :: MutableByteArray# s -> Int# -> State# s -> (#State# s, Int##)

-- | Read 16-bit integer; offset in bytes.
readInt16Array# :: MutableByteArray# s -> Int# -> State# s -> (#State# s, Int##)

-- | Read 32-bit integer; offset in bytes.
readInt32Array# :: MutableByteArray# s -> Int# -> State# s -> (#State# s, Int##)

and so on...

Change History (5)

comment:1 Changed 2 years ago by thomie

Type of failure: None/UnknownRuntime performance bug

comment:2 Changed 21 months ago by Mathnerd314

Can we instead have primops which take both an offset measured in bytes and an offset measured in terms of the type?

indexTYPEArray# :: ByteArray#          -> Int# {-byte offset-} -> Int# {-type offset-} -> TYPE#
readTYPEArray#  :: MutableByteArray# s -> Int# {-byte offset-} -> Int# {-type offset-} -> State# s -> (#State# s, TYPE##)
writeTYPEArray# :: MutableByteArray# s -> Int# {-byte offset-} -> Int# {-type offset-} -> TYPE# -> State# s -> State# s

indexTYPEOffAddr# :: Addr# -> Int# {-byte offset-} -> Int# {-type offset-} -> TYPE
readTYPEOffAddr# :: Addr# -> Int# {-byte offset-} -> Int# {-type offset-} -> State# s -> (#State# s, TYPE ##) 
writeTYPEOffAddr# :: Addr# -> Int# {-byte offset-} -> Int# {-type offset-} -> TYPE -> State# s -> State# s 

All of these go through the mkBasicIndexed{Read,Write} functions, which take both a byte offset and a type offset, so it seems reasonable to expose that.

comment:3 Changed 14 months ago by bgamari

Milestone: 8.2.1

It seems unlikely that this will happen for 8.2.

comment:4 Changed 6 months ago by bgamari

Keywords: newcomers added

If anyone is interested in picking this up do ping me. It should be a relatively straightforward patch.

comment:5 in reply to:  2 Changed 17 hours ago by sjakobi

Cc: sjakobi added

Replying to Mathnerd314:

Can we instead have primops which take both an offset measured in bytes and an offset measured in terms of the type?

indexTYPEArray# :: ByteArray#          -> Int# {-byte offset-} -> Int# {-type offset-} -> TYPE#
readTYPEArray#  :: MutableByteArray# s -> Int# {-byte offset-} -> Int# {-type offset-} -> State# s -> (#State# s, TYPE##)
writeTYPEArray# :: MutableByteArray# s -> Int# {-byte offset-} -> Int# {-type offset-} -> TYPE# -> State# s -> State# s

indexTYPEOffAddr# :: Addr# -> Int# {-byte offset-} -> Int# {-type offset-} -> TYPE
readTYPEOffAddr# :: Addr# -> Int# {-byte offset-} -> Int# {-type offset-} -> State# s -> (#State# s, TYPE ##) 
writeTYPEOffAddr# :: Addr# -> Int# {-byte offset-} -> Int# {-type offset-} -> TYPE -> State# s -> State# s 

I like these types.

All of these go through the mkBasicIndexed{Read,Write} functions, which take both a byte offset and a type offset, so it seems reasonable to expose that.

I currently don't see how this can be done. These functions require a byte offset with type ByteOff (Int) but we only have a CmmExpr. It seems to me that the new primops will require quite a bit of new plumbing down to CmmRegOff. Am I missing something?

Note: See TracTickets for help on using tickets.