From 87065c0d242d955e6f3fddf5cbc790d025c3521c Mon Sep 17 00:00:00 2001 From: Guillaume Chatelet Date: Wed, 23 Jun 2021 14:19:40 +0000 Subject: [PATCH] [libc] add benchmarks for memcmp and bzero Differential Revision: https://reviews.llvm.org/D104511 --- libc/benchmarks/CMakeLists.txt | 2 + libc/benchmarks/LibcMemoryBenchmarkMain.cpp | 47 +++++++++++++++++++-- libc/src/string/CMakeLists.txt | 38 +++++++++++++---- 3 files changed, 75 insertions(+), 12 deletions(-) diff --git a/libc/benchmarks/CMakeLists.txt b/libc/benchmarks/CMakeLists.txt index feff80cf4501..390b802bd8f7 100644 --- a/libc/benchmarks/CMakeLists.txt +++ b/libc/benchmarks/CMakeLists.txt @@ -169,3 +169,5 @@ endfunction() add_libc_multi_impl_benchmark(memcpy) add_libc_multi_impl_benchmark(memset) +add_libc_multi_impl_benchmark(bzero) +add_libc_multi_impl_benchmark(memcmp) diff --git a/libc/benchmarks/LibcMemoryBenchmarkMain.cpp b/libc/benchmarks/LibcMemoryBenchmarkMain.cpp index e3d455423de2..6fa01ede52e3 100644 --- a/libc/benchmarks/LibcMemoryBenchmarkMain.cpp +++ b/libc/benchmarks/LibcMemoryBenchmarkMain.cpp @@ -17,10 +17,14 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" +#include + namespace __llvm_libc { extern void *memcpy(void *__restrict, const void *__restrict, size_t); extern void *memset(void *, int, size_t); +extern void bzero(void *, size_t); +extern int memcmp(const void *, const void *, size_t); } // namespace __llvm_libc @@ -79,7 +83,7 @@ struct Benchmark { return [this](ParameterType P) { __llvm_libc::memcpy(DstBuffer + P.OffsetBytes, SrcBuffer + P.OffsetBytes, P.SizeBytes); - return DstBuffer + P.OffsetBytes; + return DstBuffer[P.OffsetBytes]; }; } @@ -97,18 +101,55 @@ struct Benchmark { return [this](ParameterType P) { __llvm_libc::memset(DstBuffer + P.OffsetBytes, P.OffsetBytes & 0xFF, P.SizeBytes); - return DstBuffer + P.OffsetBytes; + return DstBuffer[P.OffsetBytes]; }; } AlignedBuffer DstBuffer; }; +#elif defined(LIBC_BENCHMARK_FUNCTION_BZERO) +struct Benchmark { + static constexpr auto GetDistributions = &getMemsetSizeDistributions; + static constexpr size_t BufferCount = 1; + + Benchmark(const size_t BufferSize) : DstBuffer(BufferSize) {} + + inline auto functor() { + return [this](ParameterType P) { + __llvm_libc::bzero(DstBuffer + P.OffsetBytes, P.SizeBytes); + return DstBuffer[P.OffsetBytes]; + }; + } + + AlignedBuffer DstBuffer; +}; +#elif defined(LIBC_BENCHMARK_FUNCTION_MEMCMP) +struct Benchmark { + static constexpr auto GetDistributions = &getMemcmpSizeDistributions; + static constexpr size_t BufferCount = 2; + + Benchmark(const size_t BufferSize) + : BufferA(BufferSize), BufferB(BufferSize) { + // The memcmp buffers always compare equal. + memset(BufferA.begin(), 0xF, BufferSize); + memset(BufferB.begin(), 0xF, BufferSize); + } + + inline auto functor() { + return [this](ParameterType P) { + return __llvm_libc::memcmp(BufferA + P.OffsetBytes, + BufferB + P.OffsetBytes, P.SizeBytes); + }; + } + + AlignedBuffer BufferA; + AlignedBuffer BufferB; +}; #else #error "Missing LIBC_BENCHMARK_FUNCTION_XXX definition" #endif struct Harness : Benchmark { - Harness(const size_t BufferSize, size_t BatchParameterCount, std::function SizeSampler, std::function OffsetSampler) diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt index 4dd8ee0bf4a2..97ac99cb89fe 100644 --- a/libc/src/string/CMakeLists.txt +++ b/libc/src/string/CMakeLists.txt @@ -58,14 +58,6 @@ add_entrypoint_object( .string_utils ) -add_entrypoint_object( - memcmp - SRCS - memcmp.cpp - HDRS - memcmp.h -) - add_entrypoint_object( memmove SRCS @@ -280,7 +272,6 @@ function(add_bzero bzero_name) .memory_utils.memory_utils libc.include.string COMPILE_OPTIONS - -fno-builtin-memset -fno-builtin-bzero ${ARGN} ) @@ -297,3 +288,32 @@ else() add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) add_bzero(bzero) endif() + +# ------------------------------------------------------------------------------ +# memcmp +# ------------------------------------------------------------------------------ + +function(add_memcmp memcmp_name) + add_implementation(memcmp ${memcmp_name} + SRCS ${LIBC_SOURCE_DIR}/src/string/memcmp.cpp + HDRS ${LIBC_SOURCE_DIR}/src/string/memcmp.h + DEPENDS + .memory_utils.memory_utils + libc.include.string + COMPILE_OPTIONS + -fno-builtin-memcmp + ${ARGN} + ) +endfunction() + +if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) + add_memcmp(memcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) + add_memcmp(memcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) + add_memcmp(memcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) + add_memcmp(memcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) + add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) + add_memcmp(memcmp) +else() + add_memcmp(memcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) + add_memcmp(memcmp) +endif()