[PATCH v2] aarch64: thunderx2 memcpy branches reordering
Anton Youdkevitch
anton.youdkevitch@bell-sw.com
Fri Mar 22 19:38:00 GMT 2019
Wilco,
Thanks a lot for your comments.
On 3/22/2019 19:18, Wilco Dijkstra wrote:
> Hi Anton,
>
>> Rewrote the branches in load and merge chunk
>> so that the order is more in line with the
>> most probable case.
>
> Why not make the code more efficient as well? The loop has 2 redundant
> moves and the code for each alignment is twice as large as it could be.
> It's not a large amount of effort to do better, see below.
>
> @@ -557,17 +558,9 @@ L(ext_size_ ## shft):;\
> ext A_v.16b, C_v.16b, D_v.16b, 16-shft;\
> ext B_v.16b, D_v.16b, E_v.16b, 16-shft;\
>
> These instructions are already part of the main loop, so why not directly
> branch into it rather than repeat them?
Mostly for clarity - branching inside a loop is not a very
obvious thing.
> subs count, count, 32;\
> - b.ge 2f;\
> + b.lt 2f;\
>
> This branch is completely redundant since count is always larger than 32.
Yep, you are right. Thanks.
> 1:;\
> stp A_q, B_q, [dst], #32;\
> - ext H_v.16b, E_v.16b, F_v.16b, 16-shft;\
> - ext I_v.16b, F_v.16b, G_v.16b, 16-shft;\
> - stp H_q, I_q, [dst], #16;\
> - add dst, dst, tmp1;\
> - str G_q, [dst], #16;\
> - b L(copy_long_check32);\
> -2:;\
> - stp A_q, B_q, [dst], #32;\
> prfm pldl1strm, [src, MEMCPY_PREFETCH_LDR];\
> ldp D_q, J_q, [src], #32;\
> ext H_v.16b, E_v.16b, F_v.16b, 16-shft;\
> @@ -579,8 +572,15 @@ L(ext_size_ ## shft):;\
> ext B_v.16b, D_v.16b, J_v.16b, 16-shft;\
> mov E_v.16b, J_v.16b;\
>
> Redundant move in loop (2x). You might as well execute the next ext!
Yes, I might if I wasn't in the loop. As I constrained by the finite
number of register names I need a value in a particular
register. The fact that it is already in some other register does
not help me here. We have the window spanning 5 registers
and we load only 4 registers each iteration. So, how do I update
the fifth one?
I agree that 2 moves are redundant in this case, of course.
> subs count, count, 64;\
> - b.ge 2b;\
> - b 1b;\
> + b.ge 1b;\
> +2:;\
> + stp A_q, B_q, [dst], #32;\
> + ext H_v.16b, E_v.16b, F_v.16b, 16-shft;\
> + ext I_v.16b, F_v.16b, G_v.16b, 16-shft;\
>
> These instructions appear in the loop already, why not break out of
> the loop after executing them?
Again, this is only for clarity reasons.
> + stp H_q, I_q, [dst], #16;\
> + add dst, dst, tmp1;\
> + str G_q, [dst], #16;\
> + b L(copy_long_check32);\
>
> These instructions are invariant with respect to alignment, so why repeat
> these many times?
You are right, invariants should be hoisted. And they will.
More information about the Libc-alpha
mailing list