mbutrovich commented on code in PR #11656:
URL: https://github.com/apache/arrow-rs/pull/11656#discussion_r4316821659


##########
arrow-data/src/transform/mod.rs:
##########
@@ -226,13 +226,12 @@ fn build_extend_view(array: &ArrayData, buffer_offset: 
u32) -> Extend<'_> {
             mutable
                 .buffer1
                 .extend(views[start..start + len].iter().map(|v| {

Review Comment:
   > the branchless view copy is indeed the culprit here. I had Claude explore 
a bunch of alternatives and it seems that rather than unpacking and repacking 
the view, we can use this trick instead
   
   The codegen agrees with that. I built `arrow-data` with the release profile 
for `x86_64-unknown-linux-gnu` (rustc 1.99.0). At e2eecf1, the repack sends the 
high half of each view through an SSE register to clear the old buffer index:
   
   ```asm
   movq    xmm1, qword ptr [r8 + 8]       # high 64 bits of the view
   ...
   add     r11d, dword ptr [r8 + 8]       # new buffer index
   pand    xmm1, xmm0                     # clear the old buffer index
   movq    rbx, xmm1
   or      rbx, r11                       # merge in the new one
   ```
   
   At 2edf0bb, the offset is added straight into the high word from memory. 
There is no SSE round trip, and LLVM unrolls the loop by two:
   
   ```asm
   cmp     r15d, 13
   mov     r12d, 0
   cmovae  r12d, r11d                     # buffer_offset, or 0 for an inline 
view
   add     r12, qword ptr [r8 + r14 - 8]  # high 64 bits + offset
   ```
   
   On aarch64 the `and` / `add w` / `orr` repack becomes a single `add x13, 
x15, x13`. That takes the loop from 11 to 9 instructions per view.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to