RE: [PATCH] eal/x86: optimize memcpy of small 64-byte blocks
Morten Brørup <[email protected]>
| Newsgroups | org.dpdk.dev |
|---|---|
| Message-ID | <[email protected]> |
> From: Morten Brørup [mailto:[email protected]] > Sent: Tuesday, 4 August 2026 16.33 > > The implementation for copying 64-byte blocks up to 512 (or 256) bytes > does not depend on address alignment with the size of the CPU's vector > registers, but is implemented in both unaligned and aligned copy > functions. > The main rte_memcpy() function was updated, so > if the copy size is known at compile time and the other criteria match, > the copy is performed without checking alignment requirements. > This provides two benefits when the optimization comes into play: > 1. A performance gain, because the address alignment check is avoided. > 3. Reduced instruction memory footprint, because the compiler only > generates one instance of the function for copying, instead of two > instances (one in the unaligned copy function, and one in the aligned > copy function). > > Furthermore, the temporary alignment mask definition (ALIGNMENT_MASK) > was prefixed by RTE_MEMCPY_ to prevent potential namespace collision. > > And finally, the superfluous function declaration at the top of the > file was removed, and its description was moved to the function > definition. > This improves search results with source code browsers. > > Signed-off-by: Morten Brørup <[email protected]> > --- The AI in the CI is confused, so the AI Code Review warning in Patchwork can be ignored. Quoting and commenting AI code review: > ### 1. Bitwise test incorrect for 512-byte blocks > > **File:** `lib/eal/x86/include/rte_memcpy.h:712` > > ```c > if (n & 512) { > ``` > > **Issue:** > This test is wrong. > `n & 512` is true when bit 9 is set, which occurs for n=512, n=513, ..., n=767, and many other values outside the intended range. > For a size of exactly 512 bytes, you want `n == 512` or `n >= 512` (with an upper bound already enforced by the outer `if`). Rubbish. Combined with the overall criteria for entering this at all, the test matches 512 exactly as intended. > > **Why it matters:** > With `n=128`, the expression `128 & 512` evaluates to 0 (correct, no copy). > But with `n=640` (which is > `RTE_MEMCPY_BLOCK_64_MAX` on AVX and shouldn't reach this code on AVX512), > if it did reach here, `640 & 512 = 512` would be true and trigger a 512-byte copy when only 640 bytes total are requested. Irrelevant. It doesn't come here when n > 512. > > More critically, the surrounding checks are also bitwise tests (`n & 256`, `n & 128`, `n & 64`), > which means this code assumes `n` is a combination of these powers of two. > But the entry condition is `n <= RTE_MEMCPY_BLOCK_64_MAX` and `(n & 63) == 0`, which allows any multiple of 64 up to the max (64, 128, 192, 256, 320, 384, 448, 512). Correct. > For `n=192`, all four bitwise tests fail and nothing is copied. Wrong. 192 = 128 + 64, so both of those will execute. > For `n=320`, `n & 256 = 256` is true so it copies 256 bytes, then `n & 64 = 64` is true so it copies another 64 bytes from offset 256, which is correct only by accident (320 = 256+64). Not by accident, by design.