From 9e8c1ef826ea1f6cc624855555c36c4d38e72818 Mon Sep 17 00:00:00 2001 From: George Steed Date: Sun, 27 Sep 2026 18:53:50 +0100 Subject: [PATCH] AArch64: Avoid LD4 in ScaleRowDown4_NEON ScaleRowDown4_NEON uses LD4 to extract the third entry from each four, however LD4 is known to be slow on some micro-architectures and implies overhead for performing the de-interleaving even for the unused vectors v0/v1/v3. Replace this with a single LD1 to load the vectors without de-interleaving and then select the bytes we want with UZP instead. Speedup versus the existing Neon implementation (higher is better): Cortex-A55: 1.004 Cortex-X4: 1.873 Cortex-A720: 1.285 C1-Nano: 1.330 C1-Pro: 1.246 C1-Ultra: 1.219 Change-Id: Ib7d8633635fa149b692e433062fc4b9717a32594 Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8692146 Reviewed-by: richard winterton Reviewed-by: Frank Barchard --- source/scale_neon64.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/scale_neon64.cc b/source/scale_neon64.cc index 0f2a2013a..8d0fec14c 100644 --- a/source/scale_neon64.cc +++ b/source/scale_neon64.cc @@ -110,8 +110,11 @@ void ScaleRowDown4_NEON(const uint8_t* src_ptr, (void)src_stride; asm volatile( "1: \n" - "ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // src line 0 + "ld1 {v0.16b, v1.16b, v2.16b, v3.16b}, [%0], #64 \n" "subs %w2, %w2, #16 \n" // 16 processed per loop + "uzp2 v0.8h, v0.8h, v1.8h \n" + "uzp2 v2.8h, v2.8h, v3.8h \n" + "uzp1 v2.16b, v0.16b, v2.16b \n" "prfm pldl1keep, [%0, 448] \n" // prefetch 7 lines ahead "st1 {v2.16b}, [%1], #16 \n" "b.gt 1b \n"