Re: [PATCH 08/20] alpha: fold null and difference tests in strcmp aligned loop

Adhemerval Zanella Netto <[email protected]>
Newsgroups gmane.comp.lib.glibc.alpha
Organization Linaro
Message-ID <[email protected]>

On 11/08/26 22:19, Matt Turner wrote:
> The co-aligned main loop tested for a difference (xor; bne) and for the
> terminating null (cmpbge; beq) with two separate branches per quadword.
> On EV6/EV7 the loop is issue-bound and right at the one-branch-per-cycle
> limit, so the second branch is a bottleneck.
> 
> Combine the two into a single syndrome -- "or" of the difference bits and
> the null mask -- so one branch closes the loop and the difference test for
> the first word moves out into the head.  The loop still loads the next
> word only after the current one tests clean (a zero syndrome implies no
> null, so the string continues and the next word is mapped), so it never
> reads past the terminating null onto an unmapped page.
> 
> bench-strcmp on EV7 (21364): co-aligned compares ~6-9% faster across
> lengths that stay in L1, neutral once memory-bound; the mutually
> misaligned path is unchanged.  Passes string/test-strcmp.

The alpha strcmp.S is another potential candidate to be removed, the
generic implementation contains all the optimizations bits (word aligned
loops, word unaligned loop, and mismatch/EOS tails) and will use all
the require alpha instruction to speed them up.

> ---
>  sysdeps/alpha/strcmp.S | 24 +++++++++++++++++-------
>  1 file changed, 17 insertions(+), 7 deletions(-)
> 
> diff --git ./sysdeps/alpha/strcmp.S ./sysdeps/alpha/strcmp.S
> index c7f092d1b7..6454b7aab0 100644
> --- ./sysdeps/alpha/strcmp.S
> +++ ./sysdeps/alpha/strcmp.S
> @@ -53,22 +53,32 @@ $aligned:
>  	ornot	t0, t3, t0	# .. e1 :
>  	cmpbge	zero, t1, t7	# e0    : bits set iff null found
>  	bne	t7, $eos	# e1 (zdb)
> +	xor	t0, t1, t2	# e0    : difference in the first word?
> +	bne	t2, $wordcmp	# .. e1 (zdb)
> +
> +	/* Aligned compare main loop.  Fold the difference test (xor) and the
> +	   null test (cmpbge) into a single syndrome with "or", so one branch
> +	   per quadword closes the loop instead of two.  Each load is gated by
> +	   the previous word being clean -- a zero syndrome means no null, so
> +	   the string continues and the next word is mapped -- hence we never
> +	   read past the terminating null onto an unmapped page.
>  
> -	/* Aligned compare main loop.
>  	   On entry to this basic block:
>  	   t0 == an s1 word.
> -	   t1 == an s2 word not containing a null.  */
> +	   t1 == an s2 word, equal to t0 and not containing a null.  */
>  
>  $a_loop:
> -	xor	t0, t1, t2	# e0	:
> -	bne	t2, $wordcmp	# .. e1 (zdb)
>  	ldq_u	t1, 8(a1)	# e0    :
>  	ldq_u	t0, 8(a0)	# .. e1 :
>  	addq	a1, 8, a1	# e0    :
>  	addq	a0, 8, a0	# .. e1 :
> -	cmpbge	zero, t1, t7	# e0    :
> -	beq	t7, $a_loop	# .. e1 (zdb)
> -	br	$eos		# e1    :
> +	xor	t0, t1, t2	# e0    : bytes that differ
> +	cmpbge	zero, t1, t7	# .. e1 : bits set iff null found
> +	or	t2, t7, t8	# e0    : syndrome = difference | null
> +	beq	t8, $a_loop	# .. e1 (zdb) : clean word, keep going
> +
> +	bne	t7, $eos	# e0    : null present (handles diff-before-null)
> +	br	$wordcmp	# .. e1 : a pure difference, no null
>  
>  	/* The two strings are not co-aligned.  Align s1 and cope.  */
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.