[PATCH] aarch64: thunderx2 memmove performance improvements
Anton Youdkevitch
anton.youdkevitch@bell-sw.com
Mon Apr 15 15:53:00 GMT 2019
Wilco,
Thanks a lot for your comments and suggestions.
I attached the upated patch.
On 4/12/2019 21:03, Wilco Dijkstra wrote:
> Hi Anton,
>
> This looks like a good cleanup! A few comments and suggestions for
> improvements:
>
> 0. The diff is quite large due to tab/space changes. Would it be possible to split
> this into a separate patch?
Sure, I will then send the tab/space cleanup patch later.
> 1. There are a few cases where ldp or stp could be used, but isn't, eg:
>
> + str B_q, [dst], #16
> + ldp H_q, I_q, [src], #32
> + str C_q, [dst], #16
>
> Why not do stp B_q, C_q, [dst], 32?
This is the remains of trying to manually schedule the instructions.
Fixed.
> 2. There are a lot of writeback instructions used in cases where this isn't
> strictly required. Have you noticed this actually improves performance? Even
> if required for the main loop, it is best to reduce them where possible:
But there are no writebacks in the main loop - they are only in the loop's
tails, aren't they?
> +L(loop128_exit0):
> + ldp F_q, G_q, [srcend, -64]
> + ldp H_q, I_q, [srcend, -32]
> + stp B_q, C_q, [dst], #32
> + stp D_q, E_q, [dst], #32
> + stp F_q, G_q, [dstend, -64]
> + stp H_q, I_q, [dstend, -32]
> + ret
>
> L(loop128_exit1):
> + ldp B_q, C_q, [srcend, -64]
> + ldp D_q, E_q, [srcend, -32]
> + stp F_q, G_q, [dst], #32
> + stp H_q, I_q, [dst], #32
> + stp B_q, C_q, [dstend, -64]
> + stp D_q, E_q, [dstend, -32]
> + ret
>
> Here dst is not used but incremented twice.
Right, good catch, thanks!
Done.
> 3. Missed optimization:
>
> +L(dst_unaligned_tail):
> + ldp C_q, D_q, [srcend, -64]
> + ldp E_q, F_q, [srcend, -32]
> + stp A_q, B_q, [dst], #32
> + stp H_q, I_q, [dst], #32
> + add dst, dst, tmp1
> + str G_q, [dst, -16]
> + stp C_q, D_q, [dstend, -64]
> + stp E_q, F_q, [dstend, -32]
> ret
>
> Surely this could use str G_q, [dst, tmp1] if we change the writeback on the stp?
Done.
> 4. Unrolling can be more efficient:
>
> L(loop128):
> + ldp F_q, G_q, [src], #32
> + ldp H_q, I_q, [src], #32
> + stp B_q, C_q, [dst], #32
> + stp D_q, E_q, [dst], #32
> + subs count, count, 64
> + b.lt L(loop128_exit1)
> + ldp B_q, C_q, [src], #32
> + ldp D_q, E_q, [src], #32
> + stp F_q, G_q, [dst], #32
> + stp H_q, I_q, [dst], #32
> + subs count, count, 64
> + b.ge L(loop128)
> +L(loop128_exit0):
> The idea of unrolling 2x is to only have a single loop branch. Using a single branch
> makes it easier to remove all the writebacks too - you only need 2 rather than 8!
The idea was to minimize the length of the loop tail. For branchless 128
bytes per iteration loop the branchless tail needs to read 128 bytes.
For the branched loop as the one above the tail processes only 64
bytes. And I don't see how I can avoid writebacks of up to 127 bytes
in the branchless tails for your version.
--
Thanks,
Anton
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-AARCH64-thunderx2-memmove-performance-improvements.patch
Type: text/x-diff
Size: 16066 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20190415/2fda3bde/attachment.bin>
More information about the Libc-alpha
mailing list