[PATCH 4/6] newlib: memmove: improve performance for overlapping buffers

Alexey Lapshin alexey.lapshin@espressif.com
Mon Jan 27 10:46:58 GMT 2025


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
---
 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 4c5ec6f83..343210680 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
     {
-- 
2.43.0



More information about the Newlib mailing list