From dec7d9c015c481dfa2d46d3a91023ce311bd2699 Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Fri, 4 Mar 2022 13:43:25 +0000 Subject: [PATCH] NFC memcpy: move small_copies test to Arch::copy While small_copies seems suitable in general and, in particular, on X86, it appears to be slower than a byte-wise loop on PowerPC. --- src/mem/memcpy.h | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/mem/memcpy.h b/src/mem/memcpy.h index 40eea5e..b28e5e1 100644 --- a/src/mem/memcpy.h +++ b/src/mem/memcpy.h @@ -161,9 +161,20 @@ namespace snmalloc * Hook for architecture-specific optimisations. Does nothing in the * default case. */ - static SNMALLOC_FAST_PATH_INLINE bool copy(void*, const void*, size_t) + static SNMALLOC_FAST_PATH_INLINE void + copy(void* dst, const void* src, size_t len) { - return false; + // If this is a small size, use a jump table for small sizes. + if (len <= LargestRegisterSize) + { + small_copies(dst, src, len); + } + // Otherwise do a simple bulk copy loop. + else + { + block_copy(dst, src, len); + copy_end(dst, src, len); + } } }; @@ -189,13 +200,20 @@ namespace snmalloc /** * Platform-specific copy hook. For large copies, use `rep movsb`. */ - static SNMALLOC_FAST_PATH_INLINE bool + static SNMALLOC_FAST_PATH_INLINE void copy(void* dst, const void* src, size_t len) { + // If this is a small size, use a jump table for small sizes, like on the + // generic architecture case above. + if (len <= LargestRegisterSize) + { + small_copies(dst, src, len); + } + // The Intel optimisation manual recommends doing this for sizes >256 // bytes on modern systems and for all sizes on very modern systems. // Testing shows that this is somewhat overly optimistic. - if (SNMALLOC_UNLIKELY(len >= 512)) + else if (SNMALLOC_UNLIKELY(len >= 512)) { // Align to cache-line boundaries if possible. unaligned_start<64, LargestRegisterSize>(dst, src, len); @@ -213,9 +231,14 @@ namespace snmalloc # else # error No inline assembly or rep movsb intrinsic for this compiler. # endif - return true; } - return false; + + // Otherwise do a simple bulk copy loop. + else + { + block_copy(dst, src, len); + copy_end(dst, src, len); + } } }; #endif @@ -262,18 +285,7 @@ namespace snmalloc src, len, "memcpy with source out of bounds of heap allocation"); } - // If this is a small size, use a jump table for small sizes. - if (len <= Arch::LargestRegisterSize) - { - small_copies(dst, src, len); - } - // If there's an architecture-specific hook, try using it. Otherwise do a - // simple bulk copy loop. - else if (!Arch::copy(dst, src, len)) - { - block_copy(dst, src, len); - copy_end(dst, src, len); - } + Arch::copy(dst, src, len); return orig_dst; } } // namespace