teknoraver

riscv memcpy

Mar 11th, 2026
8,649
0
224 days
3
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 4.92 KB | None | 0 0
  1. From 03e7d69cff6b206870d841f2398f8040608df7f4 Mon Sep 17 00:00:00 2001
  2. From: Matteo Croce <[email protected]>
  3. Date: Thu, 29 Jan 2026 02:02:11 +0100
  4. Subject: [PATCH v2] riscv: memcpy: fast copy for unaligned buffers
  5.  
  6. The RISC-V memcpy() does an 8 byte wide copy when the two buffers have
  7. the same alignment, and fallbacks to a single byte copy otherwise.
  8.  
  9. Implement a unaligned aware 8 byte copy when buffers are unaligned
  10. which copies 8 bytes at time by doing proper shifting.
  11.  
  12. Synthetic benchmarks[1] show that the aligned code path is unaffected,
  13. while the unaligned one gets a ~2.3x boost:
  14.  
  15.   Before:
  16.       memcpy: aligned copy of 400 MBytes in 429 msecs (931 MB/s)
  17.       memcpy: unaligned copy of 400 MBytes in 1202 msecs (332 MB/s)
  18.  
  19.   After:
  20.       memcpy: aligned copy of 400 MBytes in 428 msecs (933 MB/s)
  21.       memcpy: unaligned copy of 400 MBytes in 519 msecs (770 MB/s)
  22.  
  23. Network RX benchmarks on a Milk-V Megrez (ESWIN EIC7700X) with a
  24. 1 Gbps NIC (stmmac driver) confirm the improvement in a real-world
  25. scenario. UDP RX flood with varying frame sizes:
  26.  
  27.   Frame size    stock memcpy     optimized memcpy     Improvement
  28.   ----------    ------------     ----------------     -----------
  29.    64 bytes      242.6 Kpps        246.9 Kpps           +1.8%
  30.   128 bytes      225.3 Kpps        243.0 Kpps           +7.9%
  31.   256 bytes      200.8 Kpps        227.8 Kpps          +13.4%
  32.   512 bytes      165.4 Kpps        203.6 Kpps          +23.1%
  33.  
  34. Throughput at 512-byte frames improved from 672 Mbps to 827 Mbps.
  35. The improvement scales with frame size as larger frames copy more
  36. bytes per packet. Larger frame sizes were not tested as they would
  37. saturate the 1 Gbps link.
  38.  
  39. [1] https://lore.kernel.org/lkml/20260301011209.4160-1[email protected]/
  40.  
  41. Signed-off-by: Matteo Croce <[email protected]>
  42. ---
  43. arch/riscv/lib/memcpy.S | 84 ++++++++++++++++++++++++++++++++++++++---
  44.  1 file changed, 79 insertions(+), 5 deletions(-)
  45.  
  46. diff --git a/arch/riscv/lib/memcpy.S b/arch/riscv/lib/memcpy.S
  47. index 44e009ec5fef..293f8a348cfd 100644
  48. --- a/arch/riscv/lib/memcpy.S
  49. +++ b/arch/riscv/lib/memcpy.S
  50. @@ -10,13 +10,14 @@
  51.  SYM_FUNC_START(__memcpy)
  52.     move t6, a0  /* Preserve return value */
  53.  
  54. -   /* Defer to byte-oriented copy for small sizes */
  55. -   sltiu a3, a2, 128
  56. -   bnez a3, 4f
  57. -   /* Use word-oriented copy only if low-order bits match */
  58. +   /* Check alignment first */
  59.     andi a3, t6, SZREG-1
  60.     andi a4, a1, SZREG-1
  61. -   bne a3, a4, 4f
  62. +   bne a3, a4, .Lshifted_copy
  63. +
  64. +   /* Aligned path: defer to byte-oriented copy for small sizes */
  65. +   sltiu a5, a2, 128
  66. +   bnez a5, 4f
  67.  
  68.     beqz a3, 2f  /* Skip if already aligned */
  69.     /*
  70. @@ -76,6 +77,79 @@ SYM_FUNC_START(__memcpy)
  71.     addi t6, t6, 16*SZREG
  72.     bltu a1, a3, 3b
  73.     andi a2, a2, (16*SZREG)-1  /* Update count */
  74. +   j 4f            /* Skip shifted copy section */
  75. +
  76. +.Lshifted_copy:
  77. +   /*
  78. +    * Source and dest have different alignments.
  79. +    * a3 = dest & (SZREG-1), a4 = src & (SZREG-1)
  80. +    * Align destination first, then use shifted word copy.
  81. +    */
  82. +
  83. +   /* For small sizes, just use byte copy */
  84. +   sltiu a5, a2, 16
  85. +   bnez a5, 4f
  86. +
  87. +   /* If dest is already aligned, skip to shifted loop setup */
  88. +   beqz a3, .Ldest_aligned
  89. +
  90. +   /* Calculate bytes needed to align dest: SZREG - a3 */
  91. +   neg a5, a3
  92. +   addi a5, a5, SZREG
  93. +   sub a2, a2, a5      /* Update count */
  94. +
  95. +.Lalign_dest_loop:
  96. +   lb a4, 0(a1)
  97. +   addi a1, a1, 1
  98. +   sb a4, 0(t6)
  99. +   addi t6, t6, 1
  100. +   addi a5, a5, -1
  101. +   bnez a5, .Lalign_dest_loop
  102. +
  103. +.Ldest_aligned:
  104. +   /*
  105. +    * Dest is now aligned. Check if we have enough bytes
  106. +    * remaining for word-oriented copy.
  107. +    */
  108. +   sltiu a3, a2, SZREG
  109. +   bnez a3, 4f
  110. +
  111. +   /*
  112. +    * Calculate shift amounts based on source alignment (distance).
  113. +    * distance = src & (SZREG-1), guaranteed non-zero since we only
  114. +    * reach here when src and dest had different alignments.
  115. +    */
  116. +   andi a3, a1, SZREG-1    /* a3 = distance */
  117. +   slli a4, a3, 3      /* a4 = distance * 8 (right shift amount) */
  118. +   li a5, SZREG*8
  119. +   sub a5, a5, a4      /* a5 = SZREG*8 - distance*8 (left shift) */
  120. +
  121. +   /* Align src backwards to word boundary */
  122. +   sub a1, a1, a3
  123. +
  124. +   /* Calculate end address: dest + (count rounded down to words) */
  125. +   andi a6, a2, ~(SZREG-1)
  126. +   add a6, t6, a6      /* a6 = loop end address for dest */
  127. +
  128. +   /* Load first aligned word from source */
  129. +   REG_L t0, 0(a1)
  130. +
  131. +.Lshifted_loop:
  132. +   REG_L t1, SZREG(a1) /* Load next aligned word */
  133. +   srl t2, t0, a4      /* Shift right: low part from current word */
  134. +   mv t0, t1       /* Current = next for next iteration */
  135. +   addi a1, a1, SZREG
  136. +   addi t6, t6, SZREG
  137. +   sll t3, t0, a5      /* Shift left: high part from next word */
  138. +   or t2, t2, t3       /* Combine to form output word */
  139. +   REG_S t2, -SZREG(t6)    /* Store to aligned dest */
  140. +   bltu t6, a6, .Lshifted_loop
  141. +
  142. +   /* Restore src to correct unaligned position */
  143. +   add a1, a1, a3
  144. +   /* Calculate remaining byte count */
  145. +   andi a2, a2, SZREG-1
  146. +   /* Fall through to label 4 for remaining bytes */
  147.  
  148.  4:
  149.     /* Handle trailing misalignment */
  150. --
  151. 2.53.0
  152.  
Advertisement
Comments
  • User was banned
  • User was banned
  • User was banned
Add Comment
Please, Sign In to add comment