[newlib-cygwin/main] newlib: memmove: improve performance for overlapping buffers

Corinna Vinschen corinna@sourceware.org
Mon Feb 10 14:40:53 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=2a79b76c077af110ed95590a4eafbe13faff5bf9

commit 2a79b76c077af110ed95590a4eafbe13faff5bf9
Author:     Alexey Lapshin <alexey.lapshin@espressif.com>
AuthorDate: Mon Jan 27 10:46:58 2025 +0000
Commit:     Corinna Vinschen <corinna@vinschen.de>
CommitDate: Mon Feb 10 15:31:10 2025 +0100

    newlib: memmove: improve performance for overlapping buffers
    
    This change provides word-sized copy for overlapping buffers, that could
    increase performance significantly. Performance measurement for RISCV:
    
        uint8_t buf[1024];
        memmove (buf + 4, buf, sizeof(buf) - 4);
    
    CPU cycles: 12255 -> 2076

Diff:
---
 newlib/libc/string/memmove.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/newlib/libc/string/memmove.c b/newlib/libc/string/memmove.c
index 4c5ec6f8372c..343210680d45 100644
--- a/newlib/libc/string/memmove.c
+++ b/newlib/libc/string/memmove.c
@@ -75,10 +75,28 @@ memmove (void *dst_void,
       /* Destructive overlap...have to copy backwards */
       src += length;
       dst += length;
+
+      if (!TOO_SMALL_LITTLE_BLOCK(length) && !UNALIGNED_X_Y(src, dst))
+        {
+          aligned_dst = (long*)dst;
+          aligned_src = (long*)src;
+
+          /* Copy one long word at a time if possible.  */
+          while (!TOO_SMALL_LITTLE_BLOCK(length))
+            {
+              *--aligned_dst = *--aligned_src;
+              length -= LITTLE_BLOCK_SIZE;
+            }
+
+          /* Pick up any residual with a byte copier.  */
+          dst = (char*)aligned_dst;
+          src = (char*)aligned_src;
+        }
+
       while (length--)
-	{
-	  *--dst = *--src;
-	}
+        {
+          *--dst = *--src;
+        }
     }
   else
     {


More information about the Newlib-cvs mailing list