Add and use jemalloc lib (#90)

* Add and use jemalloc lib

* Add autoconf

* Silence macro redefinition warning
This commit is contained in:
antonio2368 2021-02-15 09:52:40 +01:00 committed by Antonio Andelic
parent 25eb2c147a
commit e8810a4152
14 changed files with 145 additions and 2 deletions

View File

@ -46,6 +46,7 @@ MEMGRAPH_BUILD_DEPS=(
rpm-build rpmlint # for RPM package building
doxygen graphviz # source documentation generators
which mono-complete dotnet-sdk-3.1 golang nodejs zip unzip java-11-openjdk-devel # for driver tests
autoconf # for jemalloc code generation
)
list() {
echo "$1"

View File

@ -45,6 +45,7 @@ MEMGRAPH_BUILD_DEPS=(
doxygen graphviz # source documentation generators
which mono-complete dotnet-sdk-3.1 nodejs golang zip unzip java-11-openjdk-devel # for driver tests
sbcl # for custom Lisp C++ preprocessing
autoconf # for jemalloc code generation
)
list() {
echo "$1"

View File

@ -43,6 +43,7 @@ MEMGRAPH_BUILD_DEPS=(
doxygen graphviz # source documentation generators
mono-runtime mono-mcs zip unzip default-jdk-headless # for driver tests
dotnet-sdk-3.1 golang nodejs npm
autoconf # for jemalloc code generation
)
list() {
echo "$1"

View File

@ -41,6 +41,7 @@ MEMGRAPH_BUILD_DEPS=(
sbcl # for custom Lisp C++ preprocessing
doxygen graphviz # source documentation generators
mono-runtime mono-mcs nodejs zip unzip default-jdk-headless # for driver tests
autoconf # for jemalloc code generation
)
list() {
echo "$1"

View File

@ -42,6 +42,7 @@ MEMGRAPH_BUILD_DEPS=(
sbcl # custom Lisp C++ preprocessing
doxygen graphviz # source documentation generators
mono-runtime mono-mcs nodejs zip unzip default-jdk-headless # driver tests
autoconf # for jemalloc code generation
)
list() {
echo "$1"

View File

@ -43,6 +43,7 @@ MEMGRAPH_BUILD_DEPS=(
doxygen graphviz # source documentation generators
mono-runtime mono-mcs zip unzip default-jdk-headless # for driver tests
dotnet-sdk-3.1 golang nodejs npm
autoconf # for jemalloc code generation
)
list() {
echo "$1"

1
libs/.gitignore vendored
View File

@ -4,3 +4,4 @@
!cleanup.sh
!CMakeLists.txt
!__main.cpp
!jemalloc.cmake

View File

@ -8,6 +8,8 @@ if (NPROC EQUAL 0)
set(NPROC 1)
endif()
set(LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR})
# convenience functions
function(import_header_library name include_dir)
add_library(${name} INTERFACE IMPORTED GLOBAL)
@ -212,3 +214,5 @@ import_external_library(spdlog STATIC
${CMAKE_CURRENT_SOURCE_DIR}/spdlog/${CMAKE_INSTALL_LIBDIR}/libspdlog.a
${CMAKE_CURRENT_SOURCE_DIR}/spdlog/include
BUILD_COMMAND $(MAKE) spdlog)
include(jemalloc.cmake)

52
libs/jemalloc.cmake Normal file
View File

@ -0,0 +1,52 @@
set(JEMALLOC_DIR "${LIB_DIR}/jemalloc")
set(JEMALLOC_SRCS
${JEMALLOC_DIR}/src/arena.c
${JEMALLOC_DIR}/src/background_thread.c
${JEMALLOC_DIR}/src/base.c
${JEMALLOC_DIR}/src/bin.c
${JEMALLOC_DIR}/src/bitmap.c
${JEMALLOC_DIR}/src/ckh.c
${JEMALLOC_DIR}/src/ctl.c
${JEMALLOC_DIR}/src/div.c
${JEMALLOC_DIR}/src/extent.c
${JEMALLOC_DIR}/src/extent_dss.c
${JEMALLOC_DIR}/src/extent_mmap.c
${JEMALLOC_DIR}/src/hash.c
${JEMALLOC_DIR}/src/hook.c
${JEMALLOC_DIR}/src/jemalloc.c
${JEMALLOC_DIR}/src/large.c
${JEMALLOC_DIR}/src/log.c
${JEMALLOC_DIR}/src/malloc_io.c
${JEMALLOC_DIR}/src/mutex.c
${JEMALLOC_DIR}/src/mutex_pool.c
${JEMALLOC_DIR}/src/nstime.c
${JEMALLOC_DIR}/src/pages.c
${JEMALLOC_DIR}/src/prng.c
${JEMALLOC_DIR}/src/prof.c
${JEMALLOC_DIR}/src/rtree.c
${JEMALLOC_DIR}/src/sc.c
${JEMALLOC_DIR}/src/stats.c
${JEMALLOC_DIR}/src/sz.c
${JEMALLOC_DIR}/src/tcache.c
${JEMALLOC_DIR}/src/test_hooks.c
${JEMALLOC_DIR}/src/ticker.c
${JEMALLOC_DIR}/src/tsd.c
${JEMALLOC_DIR}/src/witness.c
${JEMALLOC_DIR}/src/safety_check.c
)
add_library(jemalloc ${JEMALLOC_SRCS})
target_include_directories(jemalloc PUBLIC "${JEMALLOC_DIR}/include")
target_compile_definitions(jemalloc PRIVATE -DJEMALLOC_NO_PRIVATE_NAMESPACE)
if (CMAKE_BUILD_TYPE STREQUAL "DEBUG")
target_compile_definitions(jemalloc PRIVATE -DJEMALLOC_DEBUG=1 -DJEMALLOC_PROF=1)
endif()
target_compile_options(jemalloc PRIVATE -Wno-redundant-decls)
# for RTLD_NEXT
target_compile_options(jemalloc PRIVATE -D_GNU_SOURCE)
set_property(TARGET jemalloc APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS USE_JEMALLOC=1)

View File

@ -121,3 +121,22 @@ clone https://github.com/memgraph/pymgclient.git pymgclient $pymgclient_tag
spdlog_tag="46d418164dd4cd9822cf8ca62a116a3f71569241" # (2020-12-01)
clone https://github.com/gabime/spdlog spdlog $spdlog_tag
jemalloc_tag="ea6b3e973b477b8061e0076bb257dbd7f3faa756" # (2021-02-11)
clone https://github.com/jemalloc/jemalloc.git jemalloc $jemalloc_tag
pushd jemalloc
# ThreadPool select job randomly, and there can be some threads that had been
# performed some memory heavy task before and will be inactive for some time,
# but until it will became active again, the memory will not be freed since by
# default each thread has it's own arena, but there should be not more then
# 4*CPU arenas (see opt.nareans description).
#
# By enabling percpu_arena number of arenas limited to number of CPUs and hence
# this problem should go away.
#
# muzzy_decay_ms -- use MADV_FREE when available on newer Linuxes, to
# avoid spurious latencies and additional work associated with
# MADV_DONTNEED. See
# https://github.com/ClickHouse/ClickHouse/issues/11121 for motivation.
./autogen.sh --with-malloc-conf="percpu_arena:percpu,oversize_threshold:0,muzzy_decay_ms:10000"
popd

View File

@ -38,7 +38,7 @@ if (MG_ENTERPRISE)
endif()
set(MG_SINGLE_NODE_V2_LIBS stdc++fs Threads::Threads
telemetry_lib mg-query mg-communication)
telemetry_lib mg-query mg-communication mg-new-delete)
if (MG_ENTERPRISE)
# These are enterprise subsystems
set(MG_SINGLE_NODE_V2_LIBS ${MG_SINGLE_NODE_V2_LIBS} mg-auth mg-audit)

View File

@ -11,3 +11,6 @@ set(utils_src_files
add_library(mg-utils STATIC ${utils_src_files})
target_link_libraries(mg-utils stdc++fs Threads::Threads spdlog fmt gflags uuid)
add_library(mg-new-delete STATIC new_delete.cpp)
target_link_libraries(mg-new-delete jemalloc)

58
src/utils/new_delete.cpp Normal file
View File

@ -0,0 +1,58 @@
#include <iostream>
#include <new>
#if USE_JEMALLOC
#include <jemalloc/jemalloc.h>
#else
#include <cstdlib>
#endif
#include "utils/likely.hpp"
namespace {
void *newImpl(std::size_t size) {
auto *ptr = malloc(size);
if (LIKELY(ptr != nullptr)) {
return ptr;
}
throw std::bad_alloc{};
}
void *newNoExcept(const std::size_t size) noexcept { return malloc(size); }
void deleteImpl(void *ptr) noexcept { free(ptr); }
#if USE_JEMALLOC
void deleteSized(void *ptr, const std::size_t size) noexcept {
if (UNLIKELY(ptr == nullptr)) {
return;
}
sdallocx(ptr, size, 0);
}
#else
void deleteSized(void *ptr, const std::size_t /*unused*/) noexcept { free(ptr); }
#endif
} // namespace
void *operator new(std::size_t size) { return newImpl(size); }
void *operator new[](std::size_t size) { return newImpl(size); }
void *operator new(std::size_t size, const std::nothrow_t & /*unused*/) noexcept { return newNoExcept(size); }
void *operator new[](std::size_t size, const std::nothrow_t & /*unused*/) noexcept { return newNoExcept(size); }
void operator delete(void *ptr) noexcept { deleteImpl(ptr); }
void operator delete[](void *ptr) noexcept { deleteImpl(ptr); }
void operator delete(void *ptr, std::size_t size) noexcept { deleteSized(ptr, size); }
void operator delete[](void *ptr, std::size_t size) noexcept { deleteSized(ptr, size); }

View File

@ -32,7 +32,7 @@ function(_add_unit_test test_cpp custom_main)
# used to help create two targets of the same name even though CMake
# requires unique logical target names
set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${exec_name})
target_link_libraries(${target_name} mg-utils gtest gmock Threads::Threads)
target_link_libraries(${target_name} mg-utils mg-new-delete gtest gmock Threads::Threads dl)
# register test
if(TEST_COVERAGE)
add_test(${target_name} env LLVM_PROFILE_FILE=${exec_name}.profraw ./${exec_name})