All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] un-improve strrchr()
       [not found] <20150628163252.GA1991@p183.telecom.by>
@ 2015-06-28 16:44 ` Alexey Dobriyan
  2015-06-28 18:01   ` Joe Perches
                     ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Alexey Dobriyan @ 2015-06-28 16:44 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel, linux

Commit 8da53d4595a53fb9a3380dd4d1c9bc24c7c9aab8
("lib/string.c: improve strrchr()") changed strrchr() implementation
from "rewind to the end and search backwards" to "search forward"
optimizing for characher not found case. However, common case is exactly
the opposite: string is absolute pathname, c is '/' always to be found.

Previous code did 1 branch per character + 1 branch for every character
in the last path component. Current code does 2 branches per characher
regardless.

Patch reverts to previous implementation (sans fixed coding style).

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---

	Cc linux-kernel

 lib/string.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

--- a/lib/string.c
+++ b/lib/string.c
@@ -313,12 +313,13 @@ EXPORT_SYMBOL(strchrnul);
  */
 char *strrchr(const char *s, int c)
 {
-	const char *last = NULL;
+	const char *p = s + strlen(s);
+
 	do {
-		if (*s == (char)c)
-			last = s;
-	} while (*s++);
-	return (char *)last;
+		if (*p == (char)c)
+			return (char *)p;
+	} while (--p >= s);
+	return NULL;
 }
 EXPORT_SYMBOL(strrchr);
 #endif

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] un-improve strrchr()
  2015-06-28 16:44 ` [PATCH] un-improve strrchr() Alexey Dobriyan
@ 2015-06-28 18:01   ` Joe Perches
  2015-06-28 19:43   ` Alexey Dobriyan
  2015-06-30 23:52   ` Chris Rorvick
  2 siblings, 0 replies; 5+ messages in thread
From: Joe Perches @ 2015-06-28 18:01 UTC (permalink / raw)
  To: Alexey Dobriyan; +Cc: akpm, linux-kernel, linux

On Sun, 2015-06-28 at 19:44 +0300, Alexey Dobriyan wrote:
> Commit 8da53d4595a53fb9a3380dd4d1c9bc24c7c9aab8
> ("lib/string.c: improve strrchr()") changed strrchr() implementation
> from "rewind to the end and search backwards" to "search forward"
> optimizing for characher not found case. However, common case is exactly
> the opposite: string is absolute pathname, c is '/' always to be found.
> 
> Previous code did 1 branch per character + 1 branch for every character
> in the last path component. Current code does 2 branches per characher
> regardless.

Are you comparing total cycles of all of the branches
in the called functions too?

As written the current version removes the strlen call.

> --- a/lib/string.c
> +++ b/lib/string.c
> @@ -313,12 +313,13 @@ EXPORT_SYMBOL(strchrnul);
>   */
>  char *strrchr(const char *s, int c)
>  {
> -	const char *last = NULL;
> +	const char *p = s + strlen(s);
> +
>  	do {
> -		if (*s == (char)c)
> -			last = s;
> -	} while (*s++);
> -	return (char *)last;
> +		if (*p == (char)c)
> +			return (char *)p;
> +	} while (--p >= s);
> +	return NULL;
>  }
>  EXPORT_SYMBOL(strrchr);
>  #endif



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] un-improve strrchr()
  2015-06-28 16:44 ` [PATCH] un-improve strrchr() Alexey Dobriyan
  2015-06-28 18:01   ` Joe Perches
@ 2015-06-28 19:43   ` Alexey Dobriyan
  2015-06-30 23:52   ` Chris Rorvick
  2 siblings, 0 replies; 5+ messages in thread
From: Alexey Dobriyan @ 2015-06-28 19:43 UTC (permalink / raw)
  To: joe; +Cc: linux-kernel, linux, akpm

Joe Perches wrote:

> On Sun, 2015-06-28 at 19:44 +0300, Alexey Dobriyan wrote:
> > Commit 8da53d4595a53fb9a3380dd4d1c9bc24c7c9aab8
> > ("lib/string.c: improve strrchr()") changed strrchr() implementation
> > from "rewind to the end and search backwards" to "search forward"
> > optimizing for characher not found case. However, common case is exactly
> > the opposite: string is absolute pathname, c is '/' always to be found.
> > 
> > Previous code did 1 branch per character + 1 branch for every character
> > in the last path component. Current code does 2 branches per characher
> > regardless.
> 
> Are you comparing total cycles of all of the branches
> in the called functions too?

I'm comparing branches to branches. For strrchr() you don't need 2xN branches
even in theory. strlen() might even be optimized (gcc does have the impudence
to inline it's own CMPB version though).

> As written the current version removes the strlen call.

It does.

> > --- a/lib/string.c
> > +++ b/lib/string.c
> > @@ -313,12 +313,13 @@ EXPORT_SYMBOL(strchrnul);
> >   */
> >  char *strrchr(const char *s, int c)
> >  {
> > -	const char *last = NULL;
> > +	const char *p = s + strlen(s);
> > +
> >  	do {
> > -		if (*s == (char)c)
> > -			last = s;
> > -	} while (*s++);
> > -	return (char *)last;
> > +		if (*p == (char)c)
> > +			return (char *)p;
> > +	} while (--p >= s);
> > +	return NULL;
> >  }
> >  EXPORT_SYMBOL(strrchr);
> >  #endif

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] un-improve strrchr()
  2015-06-28 16:44 ` [PATCH] un-improve strrchr() Alexey Dobriyan
  2015-06-28 18:01   ` Joe Perches
  2015-06-28 19:43   ` Alexey Dobriyan
@ 2015-06-30 23:52   ` Chris Rorvick
  2015-07-01 14:07     ` Alexey Dobriyan
  2 siblings, 1 reply; 5+ messages in thread
From: Chris Rorvick @ 2015-06-30 23:52 UTC (permalink / raw)
  To: Alexey Dobriyan; +Cc: akpm, linux-kernel, linux

[ resending w/o HTML formatting ]

On Sun, Jun 28, 2015 at 11:44 AM, Alexey Dobriyan <adobriyan@gmail.com> wrote:
> Previous code did 1 branch per character + 1 branch for every character
> in the last path component. Current code does 2 branches per characher
> regardless.

Shouldn't that be "+ 2 branches for every character in the last path
component"?  The structure of the loop is basically the same; you're
just performing fewer iterations if the character is found when
searching from the end.

Regards,

Chris

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] un-improve strrchr()
  2015-06-30 23:52   ` Chris Rorvick
@ 2015-07-01 14:07     ` Alexey Dobriyan
  0 siblings, 0 replies; 5+ messages in thread
From: Alexey Dobriyan @ 2015-07-01 14:07 UTC (permalink / raw)
  To: Chris Rorvick; +Cc: Andrew Morton, Linux Kernel, Rasmus Villemoes

On Wed, Jul 1, 2015 at 2:52 AM, Chris Rorvick <chris@rorvick.com> wrote:
> [ resending w/o HTML formatting ]
>
> On Sun, Jun 28, 2015 at 11:44 AM, Alexey Dobriyan <adobriyan@gmail.com> wrote:
>> Previous code did 1 branch per character + 1 branch for every character
>> in the last path component. Current code does 2 branches per characher
>> regardless.
>
> Shouldn't that be "+ 2 branches for every character in the last path
> component"?  The structure of the loop is basically the same; you're
> just performing fewer iterations if the character is found when
> searching from the end.

Yes, changelog is inaccurate.

It is "1 branch per character + 2 branches per character in
the last path component" vs "2 branches per character".

Rasmus posted benchmark (obvious rdtsc/strrchr/rdtsc) in private.

Speed highly depends on -O2/-Os setting and current mainline code
is not uniformly faster at least for me. I'll probably resend with new
and improved changelog.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-07-01 14:07 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20150628163252.GA1991@p183.telecom.by>
2015-06-28 16:44 ` [PATCH] un-improve strrchr() Alexey Dobriyan
2015-06-28 18:01   ` Joe Perches
2015-06-28 19:43   ` Alexey Dobriyan
2015-06-30 23:52   ` Chris Rorvick
2015-07-01 14:07     ` Alexey Dobriyan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.