[PATCH] aarch64:Modify the copy_long function in the SVE memcpy implementation for 32-byte aligned access
longwei (I)
longwei27@huawei.com
Fri Sep 5 00:47:02 GMT 2025
aarch64: Optimize memcpy_sve by using 32-byte alignment
The current memcpy_sve implementation shifts the destination pointer
forward to achieve only 16-byte alignment. This can lead to two
performance issues:
1. Cross-cache-line accesses: With 16-byte alignment, a 32-byte store
operation can still straddle two cache lines. This forces the CPU
to perform two separate cache line accesses, effectively doubling
the time for the store.
2. Cache bank conflicts: On some ARM microarchitectures, L1 cache is
organized into banks. 16-byte alignment can cause stores to frequently
hit the same bank, creating contention and reducing effective memory
bandwidth.
Change the implementation of memcpy_sve from shifting forward to 16-byte
alignment to shifting forward to 32-byte alignment, which is more
cache-friendly.
- All 32-byte SVE vector stores are fully contained within a
single 64-byte cache line, minimizing access latency.
- Stores are distributed across different cache banks more
evenly, preventing conflicts and maximizing throughput.
We tested the performance of `memcpy` on Kunpeng servers using the
libmicro test suite.
The results showed that using 32-byte alignment can reduce the latency
of `memcpy`.
The test results are in microseconds.
16-byte alignment:
memcpy_10 memcpy_32 memcpy_64 memcpy_128 memcpy_256 memcpy_512
0.0028 0.0028 0.0028 0.0035 0.0063 0.0122
memcpy_1k memcpy_2k memcpy_4k memcpy_8k memcpy_10k memcpy_16k
0.0165 0.0315 0.0605 0.1251 0.1597 0.2458
memcpy_32k memcpy_64k memcpy_128k memcpy_256k memcpy_512k memcpy_1m
0.512 1.024 2.048 4.096 7.936 16.8
memcpy_2m memcpy_4m memcpy_8m memcpy_10m
33.152 66.72 132.096 165.12
32-byte alignment:
memcpy_10 memcpy_32 memcpy_64 memcpy_128 memcpy_256 memcpy_512
0.0028 0.0028 0.0028 0.0035 0.0058 0.0096
memcpy_1k memcpy_2k memcpy_4k memcpy_8k memcpy_10k memcpy_16k
0.0165 0.0315 0.0614 0.121 0.1515 0.2355
memcpy_32k memcpy_64k memcpy_128k memcpy_256k memcpy_512k memcpy_1m
0.512 1.024 2.048 3.84 7.168 15.072
memcpy_2m memcpy_4m memcpy_8m memcpy_10m
29.952 60.032 119.04 147.968
No functional change.
sysdeps/aarch64/multiarch/memcpy_sve.S: Change alignment shifting from 16
bytes to 32 bytes.
---
sysdeps/aarch64/multiarch/memcpy_sve.S | 30 +++++++++++++-------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/sysdeps/aarch64/multiarch/memcpy_sve.S
b/sysdeps/aarch64/multiarch/memcpy_sve.S
index 0ba6358bbd..3418b082b1 100644
--- a/sysdeps/aarch64/multiarch/memcpy_sve.S
+++ b/sysdeps/aarch64/multiarch/memcpy_sve.S
@@ -103,22 +103,22 @@ L(copy_long):
add srcend, src, count
add dstend, dstin, count
- /* Copy 16 bytes and then align src to 16-byte alignment. */
- ldr D_q, [src]
- and tmp1, src, 15
- bic src, src, 15
+ /* Copy 32 bytes and then align src to 32-byte alignment. */
+ ldp G_q, H_q, [src]
+ and tmp1, src, 31
+ bic src, src, 31
sub dst, dstin, tmp1
- add count, count, tmp1 /* Count is now 16 too large. */
- ldp A_q, B_q, [src, 16]
- str D_q, [dstin]
- ldp C_q, D_q, [src, 48]
- subs count, count, 128 + 16 /* Test and readjust count. */
+ add count, count, tmp1 /* Count is now 32 too large. */
+ ldp A_q, B_q, [src, 32]
+ stp G_q, H_q, [dstin]
+ ldp C_q, D_q, [src, 64]
+ subs count, count, 128 + 32 /* Test and readjust count. */
b.ls L(copy64_from_end)
L(loop64):
- stp A_q, B_q, [dst, 16]
- ldp A_q, B_q, [src, 80]
- stp C_q, D_q, [dst, 48]
- ldp C_q, D_q, [src, 112]
+ stp A_q, B_q, [dst, 32]
+ ldp A_q, B_q, [src, 96]
+ stp C_q, D_q, [dst, 64]
+ ldp C_q, D_q, [src, 128]
add src, src, 64
add dst, dst, 64
subs count, count, 64
@@ -127,9 +127,9 @@ L(loop64):
/* Write the last iteration and copy 64 bytes from the end. */
L(copy64_from_end):
ldp E_q, F_q, [srcend, -64]
- stp A_q, B_q, [dst, 16]
+ stp A_q, B_q, [dst, 32]
ldp A_q, B_q, [srcend, -32]
- stp C_q, D_q, [dst, 48]
+ stp C_q, D_q, [dst, 64]
stp E_q, F_q, [dstend, -64]
stp A_q, B_q, [dstend, -32]
ret
--
2.43.0
More information about the Libc-alpha
mailing list