feat: use an optimized memcpy if possible

This commit is contained in:
Marcus Holland-Moritz 2025-04-10 18:45:04 +02:00
parent 35a1b95fb2
commit 7de8cf9344
4 changed files with 54 additions and 3 deletions

View File

@ -21,7 +21,7 @@ cmake_minimum_required(VERSION 3.28.0)
# Enable CMAKE_MSVC_RUNTIME_LIBRARY
cmake_policy(SET CMP0091 NEW)
project(dwarfs)
project(dwarfs LANGUAGES CXX C)
include(ExternalProject)
include(CheckCXXSourceCompiles)

View File

@ -29,6 +29,15 @@ add_library(
tools/src/tool/tool.cpp
)
# TODO: Try enabling folly memcpy also for ARM if we figure out how that works :-)
if(STATIC_BUILD_DO_NOT_USE AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
enable_language(ASM)
target_sources(dwarfs_tool PRIVATE folly/folly/memcpy.S)
set_property(SOURCE folly/folly/memcpy.S APPEND PROPERTY COMPILE_OPTIONS "-x" "assembler-with-cpp" "-D__AVX2__")
target_link_options(dwarfs_tool PUBLIC -Wl,--wrap=memcpy)
target_compile_definitions(dwarfs_tool PRIVATE -DDWARFS_USE_FOLLY_MEMCPY)
endif()
if(WITH_MAN_OPTION)
target_sources(dwarfs_tool PRIVATE
tools/src/tool/pager.cpp

View File

@ -42,8 +42,7 @@ class main_adapter {
public:
using main_fn_type = int (*)(int, sys_char**, iolayer const&);
explicit main_adapter(main_fn_type main_fn)
: main_fn_(main_fn) {}
explicit main_adapter(main_fn_type main_fn);
int operator()(int argc, sys_char** argv) const;
int operator()(std::span<std::string const> args, iolayer const& iol) const;

View File

@ -26,12 +26,48 @@
* SPDX-License-Identifier: MIT
*/
#include <iostream>
#include <vector>
#include <dwarfs/util.h>
#include <dwarfs/tool/iolayer.h>
#include <dwarfs/tool/main_adapter.h>
#include <dwarfs/tool/safe_main.h>
#ifdef DWARFS_USE_FOLLY_MEMCPY
extern "C" {
extern void* __real_memcpy(void* dest, void const* src, size_t size);
extern void* __folly_memcpy(void* dest, void const* src, size_t size);
}
namespace {
static void* (*the_memcpy)(void*, void const*, size_t) = &__real_memcpy;
void select_memcpy() {
bool const debug = dwarfs::getenv_is_enabled("DWARFS_DEBUG_MEMCPY");
if (__builtin_cpu_supports("avx2")) {
the_memcpy = &__folly_memcpy;
if (debug) {
std::cerr << "Using AVX2 memcpy\n";
}
} else if (debug) {
std::cerr << "Using default memcpy\n";
}
}
} // namespace
extern "C" void*
__wrap_memcpy(void* __restrict dest, void const* __restrict src, size_t size) {
return the_memcpy(dest, src, size);
}
#endif // DWARFS_USE_FOLLY_MEMCPY
namespace dwarfs::tool {
namespace {
@ -52,6 +88,13 @@ int call_sys_main_iolayer(std::span<T> args, iolayer const& iol,
} // namespace
main_adapter::main_adapter(main_fn_type main_fn)
: main_fn_(main_fn) {
#ifdef DWARFS_USE_FOLLY_MEMCPY
select_memcpy();
#endif
}
int main_adapter::operator()(int argc, sys_char** argv) const {
return main_fn_(argc, argv, iolayer::system_default());
}