* [PATCH] i386: less assembly in strlen()
@ 2011-12-11 18:13 Alexey Dobriyan
2011-12-12 18:37 ` [tip:x86/asm] x86/i386: Use less assembly in strlen(), speed things up a bit tip-bot for Alexey Dobriyan
0 siblings, 1 reply; 3+ messages in thread
From: Alexey Dobriyan @ 2011-12-11 18:13 UTC (permalink / raw)
To: tglx, mingo, hpa; +Cc: x86, linux-kernel
Current i386 strlen() hardcodes NOT/DEC sequence. DEC is mentioned
to be suboptimal on Core2. So, put only REPNE SCASB sequence in assembly,
compiler can do the rest.
The difference in generated code is like below (MCORE2=y):
<strlen>:
push %edi
mov $0xffffffff,%ecx
mov %eax,%edi
xor %eax,%eax
repnz scas %es:(%edi),%al
not %ecx
- dec %ecx
- mov %ecx,%eax
+ lea -0x1(%ecx),%eax
pop %edi
ret
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
arch/x86/lib/string_32.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
--- a/arch/x86/lib/string_32.c
+++ b/arch/x86/lib/string_32.c
@@ -164,15 +164,13 @@ EXPORT_SYMBOL(strchr);
size_t strlen(const char *s)
{
int d0;
- int res;
+ size_t res;
asm volatile("repne\n\t"
- "scasb\n\t"
- "notl %0\n\t"
- "decl %0"
+ "scasb"
: "=c" (res), "=&D" (d0)
: "1" (s), "a" (0), "0" (0xffffffffu)
: "memory");
- return res;
+ return ~res - 1;
}
EXPORT_SYMBOL(strlen);
#endif
^ permalink raw reply [flat|nested] 3+ messages in thread
* [tip:x86/asm] x86/i386: Use less assembly in strlen(), speed things up a bit
2011-12-11 18:13 [PATCH] i386: less assembly in strlen() Alexey Dobriyan
@ 2011-12-12 18:37 ` tip-bot for Alexey Dobriyan
2011-12-12 18:54 ` Linus Torvalds
0 siblings, 1 reply; 3+ messages in thread
From: tip-bot for Alexey Dobriyan @ 2011-12-12 18:37 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, torvalds, JBeulich, tglx, adobriyan,
mingo
Commit-ID: 890890cb8e415e1e7a61bfe3c8e246f710196824
Gitweb: http://git.kernel.org/tip/890890cb8e415e1e7a61bfe3c8e246f710196824
Author: Alexey Dobriyan <adobriyan@gmail.com>
AuthorDate: Sun, 11 Dec 2011 21:13:19 +0300
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Mon, 12 Dec 2011 18:33:42 +0100
x86/i386: Use less assembly in strlen(), speed things up a bit
Current i386 strlen() hardcodes NOT/DEC sequence. DEC is
mentioned to be suboptimal on Core2. So, put only REPNE SCASB
sequence in assembly, compiler can do the rest.
The difference in generated code is like below (MCORE2=y):
<strlen>:
push %edi
mov $0xffffffff,%ecx
mov %eax,%edi
xor %eax,%eax
repnz scas %es:(%edi),%al
not %ecx
- dec %ecx
- mov %ecx,%eax
+ lea -0x1(%ecx),%eax
pop %edi
ret
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jan Beulich <JBeulich@suse.com>
Link: http://lkml.kernel.org/r/20111211181319.GA17097@p183.telecom.by
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
arch/x86/lib/string_32.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/arch/x86/lib/string_32.c b/arch/x86/lib/string_32.c
index 82004d2..bd59090 100644
--- a/arch/x86/lib/string_32.c
+++ b/arch/x86/lib/string_32.c
@@ -164,15 +164,13 @@ EXPORT_SYMBOL(strchr);
size_t strlen(const char *s)
{
int d0;
- int res;
+ size_t res;
asm volatile("repne\n\t"
- "scasb\n\t"
- "notl %0\n\t"
- "decl %0"
+ "scasb"
: "=c" (res), "=&D" (d0)
: "1" (s), "a" (0), "0" (0xffffffffu)
: "memory");
- return res;
+ return ~res - 1;
}
EXPORT_SYMBOL(strlen);
#endif
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [tip:x86/asm] x86/i386: Use less assembly in strlen(), speed things up a bit
2011-12-12 18:37 ` [tip:x86/asm] x86/i386: Use less assembly in strlen(), speed things up a bit tip-bot for Alexey Dobriyan
@ 2011-12-12 18:54 ` Linus Torvalds
0 siblings, 0 replies; 3+ messages in thread
From: Linus Torvalds @ 2011-12-12 18:54 UTC (permalink / raw)
To: mingo, hpa, linux-kernel, torvalds, JBeulich, tglx, adobriyan,
mingo
Cc: linux-tip-commits
On Mon, Dec 12, 2011 at 10:37 AM, tip-bot for Alexey Dobriyan
<adobriyan@gmail.com> wrote:
>
> x86/i386: Use less assembly in strlen(), speed things up a bit
We could probably remove the thing entirely, and just use the generic
strlen. Some of the rep instruction usage is just purely historic,
there's little point.
Using "repne; scasb" is possibly worth it when inlined. And especially
with the change in this patch-set, where inlining also combines with
things like expression simplification, and then things like
"strlen(s)+1" (common for sizing allocations) the compiler can
actually remove the "-1" part entirely. Then the advantage of 'repne
scas' is that it's short.
But for out-of-line, we might actually be better off with just a
traditional loop. Not because we can do multiple bytes in a go (most
kernel strings are likely short enough that it's not a big deal), but
simply because 'repne scas' is not generally all that fast.
I dunno. strlen() usually isn't very hot, so it probably doesn't
matter. The really hot paths tend to do something like computing a
hash at the same time as checking the length of the string or need
something more complex anyway (ie the "hash and find '\0' or '/' in a
pathname" that path walking does). Pure strlen() is reasonably rare.
So it probably doesn't matter. The patch looks like a nice cleanup.
Linus
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-12-12 18:55 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-11 18:13 [PATCH] i386: less assembly in strlen() Alexey Dobriyan
2011-12-12 18:37 ` [tip:x86/asm] x86/i386: Use less assembly in strlen(), speed things up a bit tip-bot for Alexey Dobriyan
2011-12-12 18:54 ` Linus Torvalds
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox