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

Message ID 0a7430ca97cc851c5a7d597977ce6879115783ac.camel@espressif.com
State New
Headers
Series Refactor and optimize string/memory functions |

Commit Message

Alexey Lapshin Jan. 27, 2025, 10:46 a.m. UTC
  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(-)

-- 
2.43.0
  

Patch

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
     {