Ticket #74 (new enhancement)

Opened 17 months ago

Last modified 16 months ago

expose the bytearray in primitive vectors

Reported by: choener Owned by:
Priority: minor Milestone:
Version: Keywords:
Cc: choener@…

Description

This is based on our discussion regarding vector / primitive performance. Right now, in some tight loop, I see a 20% performance dropoff due to the offset being always calculated. Hence I use bytearrays directly. They are, on the other hand terribly inconvinient in some cases.

I propose a method

expose :: Vector -> ByteArray

that exposes the underlying array directly for faster indexing operations. In addition / alternatively I'd like an operation

unsafeBaseIndex :: Vector -> elm

that works like unsafeIndex but never incorporates the offset.

The reasoning is that there are cases where we always know the offset to be zero and no slicing would ever happen.

Benchmarks on vector / primitive will follow.

Change History

Changed 17 months ago by choener

  • cc choener@… added

Changed 16 months ago by rl

To be honest, neither of these is particularly pleasing. A 20% performance hit is quite bad, though. If you show me the benchmark where this happens, I'll try to see what I can do about it. Perhaps there is a better solution, such as fixing GHC to generate better code here. If all else fails, we'll have to do something like what you suggest but I'd much prefer something higher-level.

Changed 16 months ago by choener

Hi,

I am currently playing around with it but what llvm does gives me a headache ;-)

It basically seems that all zero offsets are kept. And unfortunately I am doing stuff that in core looks like this:

let {
   y11_a84Z
   y11_a84Z =
     +#
       (indexIntArray#
          rb2_X870
          a3_sett)
       (indexIntArray#
          rb3_X86w
          (+#
             (*#
                (+#
                   (*#
                      (indexIntArray#
                         rb1_a86V
                         (+#
                            (*#
                               sc5_snX0
                               y6_a87h)
                            (indexIntArray#
                               rb_a840
                               sc3_snWY)))
                      y9_a89b)
                   sc6_snX2)
                y10_X8jw)
             (indexIntArray#
                rb_a840
                (-#
                   sc3_snWY
                   1)))) } in

where it starts to make a difference if I add or subtract some constants.

One option could be to have not "expose" but "hide" which constructs vectors from bytearrays directly but I have to think more about it. Otherwise I agree that it would be much nicer to have ghc/llvm do the zero-offset removal.

Changed 16 months ago by rl

Hmm, I'm quite surprised that LLVM doesn't remove the zero offsets. Have you tried David's patches in the current GHC head which provide information for LLVM's alias analysis? BTW, I found that passing -O3 -std-compile-opts rather than just -O3 to LLVM sometimes helps significantly (for very tedious reasons, -O3 alone should really be sufficient).

Changed 16 months ago by choener

For testing removal of zeros, I'll have to fix up larger tests. Your second suggestion of "-O3 -std-compile-opts" seems to yield another 20%. ghc-7.2.2 / ghc-head do not change much otherwise (with the primitivearray library that is based on primitive directly instead of vector).

So everything stays weird in compiler-land ;-)

Gruss, Christian

Note: See TracTickets for help on using tickets.