Support jemalloc as the default allocator on Linux (#7250)
Add jemalloc as an alternative malloc implementation for the Verilator binary. When both tcmalloc and jemalloc are available, jemalloc is preferred due to its better performance on RTLMeter. The new --enable-jemalloc flag (default=check) mirrors the existing --enable-tcmalloc behavior: auto-detected at configure time, supports both static and dynamic linking, and is disabled when --enable-dev-asan is active.
This commit is contained in:
parent
7cd49a8028
commit
bb5a9dc247
|
|
@ -36,8 +36,8 @@ jobs:
|
|||
echo "path-exclude /usr/share/info/*" | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc
|
||||
sudo apt update || \
|
||||
sudo apt update
|
||||
sudo apt install ccache mold help2man libfl-dev libgoogle-perftools-dev libsystemc-dev || \
|
||||
sudo apt install ccache mold help2man libfl-dev libgoogle-perftools-dev libsystemc-dev
|
||||
sudo apt install ccache mold help2man libfl-dev libjemalloc-dev libsystemc-dev || \
|
||||
sudo apt install ccache mold help2man libfl-dev libjemalloc-dev libsystemc-dev
|
||||
|
||||
- name: Use saved ccache
|
||||
uses: actions/cache@v5
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ jobs:
|
|||
echo "path-exclude /usr/share/info/*" | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc
|
||||
sudo apt update || \
|
||||
sudo apt update
|
||||
sudo apt install ccache mold libfl-dev libgoogle-perftools-dev libsystemc-dev || \
|
||||
sudo apt install ccache mold libfl-dev libgoogle-perftools-dev libsystemc-dev
|
||||
sudo apt install ccache mold libfl-dev libjemalloc-dev libsystemc-dev || \
|
||||
sudo apt install ccache mold libfl-dev libjemalloc-dev libsystemc-dev
|
||||
|
||||
- name: Download Verilator installation archive
|
||||
uses: actions/download-artifact@v8
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
|
|||
sudo apt-get install ccache help2man libfl-dev
|
||||
if [[ ! "$CI_RUNS_ON" =~ "ubuntu-22.04" ]]; then
|
||||
# Some conflict of libunwind verison on 22.04, can live without it for now
|
||||
sudo apt-get install libgoogle-perftools-dev ||
|
||||
sudo apt-get install libgoogle-perftools-dev
|
||||
sudo apt-get install libjemalloc-dev ||
|
||||
sudo apt-get install libjemalloc-dev
|
||||
fi
|
||||
if [[ "$CI_RUNS_ON" =~ "ubuntu-20.04" ]] || [[ "$CI_RUNS_ON" =~ "ubuntu-22.04" ]] || [[ "$CI_RUNS_ON" =~ "ubuntu-24.04" ]]; then
|
||||
sudo apt-get install libsystemc libsystemc-dev ||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ RUN apt-get update \
|
|||
libfl2 \
|
||||
libfl-dev \
|
||||
libclang-rt-18-dev \
|
||||
libgoogle-perftools-dev \
|
||||
libjemalloc-dev \
|
||||
libsystemc \
|
||||
libsystemc-dev \
|
||||
numactl \
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ RUN apt-get update \
|
|||
help2man \
|
||||
libfl2 \
|
||||
libfl-dev \
|
||||
libgoogle-perftools-dev \
|
||||
libjemalloc-dev \
|
||||
numactl \
|
||||
perl \
|
||||
perl-doc \
|
||||
|
|
|
|||
55
configure.ac
55
configure.ac
|
|
@ -64,8 +64,8 @@ AC_ARG_ENABLE([dev-asan],
|
|||
[AS_HELP_STRING([--enable-dev-asan],
|
||||
[Enable compiling Verilator with ASAN
|
||||
AddressSanitizer for memory error detection.
|
||||
This disables tcmalloc. Does not affect
|
||||
Verilated models using ASAN.])],
|
||||
This disables tcmalloc and jemalloc. Does not
|
||||
affect Verilated models using ASAN.])],
|
||||
[case "${enableval}" in
|
||||
yes) CFG_WITH_DEV_ASAN=yes ;;
|
||||
no) CFG_WITH_DEV_ASAN=no ;;
|
||||
|
|
@ -93,6 +93,27 @@ else
|
|||
AC_MSG_RESULT($CFG_WITH_TCMALLOC)
|
||||
fi
|
||||
|
||||
# Flag to enable linking Verilator with jemalloc if available
|
||||
AC_MSG_CHECKING(whether to use jemalloc)
|
||||
AC_ARG_ENABLE([jemalloc],
|
||||
[AS_HELP_STRING([--enable-jemalloc],
|
||||
[Use libjemalloc for faster dynamic memory
|
||||
management in Verilator binary. Preferred over
|
||||
tcmalloc when both are available
|
||||
@<:@default=check@:>@])],
|
||||
[case "${enableval}" in
|
||||
yes) CFG_WITH_JEMALLOC=yes ;;
|
||||
no) CFG_WITH_JEMALLOC=no ;;
|
||||
*) AC_MSG_ERROR([bad value '${enableval}' for --enable-jemalloc]) ;;
|
||||
esac],
|
||||
[CFG_WITH_JEMALLOC=check;])
|
||||
if test "$CFG_WITH_DEV_ASAN" = "yes"; then
|
||||
CFG_WITH_JEMALLOC=no
|
||||
AC_MSG_RESULT("disabled by --enable-dev-asan")
|
||||
else
|
||||
AC_MSG_RESULT($CFG_WITH_JEMALLOC)
|
||||
fi
|
||||
|
||||
# Flag to enable code coverage build with gcov
|
||||
AC_MSG_CHECKING(whether to build for gcov code coverage collection)
|
||||
AC_ARG_ENABLE([dev-gcov],
|
||||
|
|
@ -567,8 +588,10 @@ if test "$CFG_ENABLE_PARTIAL_STATIC" = "yes"; then
|
|||
_MY_LDLIBS_CHECK_OPT(CFG_LDFLAGS_SRC, -static-libstdc++)
|
||||
_MY_LDLIBS_CHECK_OPT(CFG_LDFLAGS_SRC, -Xlinker -gc-sections)
|
||||
LTCMALLOC="-Wl,--whole-archive -l:libtcmalloc_minimal.a -Wl,--no-whole-archive"
|
||||
LJEMALLOC="-Wl,--whole-archive -l:libjemalloc.a -Wl,--no-whole-archive"
|
||||
else
|
||||
LTCMALLOC=-ltcmalloc_minimal
|
||||
LJEMALLOC=-ljemalloc
|
||||
fi
|
||||
AC_SUBST(CFG_LDFLAGS_SRC)
|
||||
AC_SUBST(CFG_LDFLAGS_VERILATED)
|
||||
|
|
@ -584,11 +607,38 @@ _MY_LDLIBS_CHECK_OPT(CFG_LIBS, -latomic)
|
|||
_MY_LDLIBS_CHECK_OPT(CFG_LIBS, -lbcrypt)
|
||||
_MY_LDLIBS_CHECK_OPT(CFG_LIBS, -lpsapi)
|
||||
|
||||
# Check if jemalloc is available based on --enable-jemalloc
|
||||
# jemalloc is preferred over tcmalloc when both are available
|
||||
CFG_HAVE_JEMALLOC=no
|
||||
_MY_LDLIBS_CHECK_IFELSE(
|
||||
$LJEMALLOC,
|
||||
[if test "$CFG_WITH_JEMALLOC" != "no"; then
|
||||
CFG_LIBS="$LJEMALLOC $CFG_LIBS";
|
||||
CFG_HAVE_JEMALLOC=yes;
|
||||
# If using jemalloc, add some extra options to make the compiler not assume
|
||||
# it is using its own versions of the standard library functions
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-fno-builtin-malloc)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-fno-builtin-calloc)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-fno-builtin-realloc)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-fno-builtin-free)
|
||||
AC_DEFINE([HAVE_JEMALLOC],[1],[Defined if have jemalloc])
|
||||
fi],
|
||||
[if test "$CFG_WITH_JEMALLOC" = "yes"; then
|
||||
AC_MSG_ERROR([--enable-jemalloc was given but test for ${LJEMALLOC} failed])
|
||||
fi])
|
||||
AC_SUBST(HAVE_JEMALLOC)
|
||||
|
||||
# Check if tcmalloc is available based on --enable-tcmalloc
|
||||
# Only use tcmalloc if jemalloc was not found/enabled
|
||||
if test "$CFG_HAVE_JEMALLOC" = "yes"; then
|
||||
AC_MSG_NOTICE([jemalloc found, skipping tcmalloc check])
|
||||
else
|
||||
CFG_HAVE_TCMALLOC=no
|
||||
_MY_LDLIBS_CHECK_IFELSE(
|
||||
$LTCMALLOC,
|
||||
[if test "$CFG_WITH_TCMALLOC" != "no"; then
|
||||
CFG_LIBS="$LTCMALLOC $CFG_LIBS";
|
||||
CFG_HAVE_TCMALLOC=yes;
|
||||
# If using tcmalloc, add some extra options to make the compiler not assume
|
||||
# it is using its own versions of the standard library functions
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-fno-builtin-malloc)
|
||||
|
|
@ -600,6 +650,7 @@ _MY_LDLIBS_CHECK_IFELSE(
|
|||
[if test "$CFG_WITH_TCMALLOC" = "yes"; then
|
||||
AC_MSG_ERROR([--enable-tcmalloc was given but test for ${LTCMALLOC} failed])
|
||||
fi])
|
||||
fi
|
||||
AC_SUBST(HAVE_TCMALLOC)
|
||||
AC_SUBST(CFG_LIBS)
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ In brief, to install from git:
|
|||
|
||||
# Prerequisites:
|
||||
#sudo apt-get install git help2man perl python3 make autoconf g++ flex bison ccache
|
||||
#sudo apt-get install libgoogle-perftools-dev numactl perl-doc
|
||||
#sudo apt-get install libgoogle-perftools-dev libjemalloc-dev numactl perl-doc
|
||||
#sudo apt-get install libfl2 # Ubuntu only (ignore if gives error)
|
||||
#sudo apt-get install libfl-dev # Ubuntu only (ignore if gives error)
|
||||
#sudo apt-get install zlibc zlib1g zlib1g-dev # Ubuntu only (ignore if gives error)
|
||||
|
|
@ -144,7 +144,7 @@ installed for good performance:
|
|||
|
||||
sudo apt-get install ccache # If present at build, needed for run
|
||||
sudo apt-get install mold # If present at build, needed for run
|
||||
sudo apt-get install libgoogle-perftools-dev numactl
|
||||
sudo apt-get install libjemalloc-dev numactl
|
||||
|
||||
To build Verilator you will need to install these packages; these do not
|
||||
need to be present to run Verilator:
|
||||
|
|
|
|||
15
src/V3Os.cpp
15
src/V3Os.cpp
|
|
@ -57,6 +57,9 @@ VL_DEFINE_DEBUG_FUNCTIONS;
|
|||
#ifdef HAVE_TCMALLOC
|
||||
#include <gperftools/malloc_extension.h>
|
||||
#endif
|
||||
#ifdef HAVE_JEMALLOC
|
||||
#include <jemalloc/jemalloc.h>
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
#if defined(_WIN32) || defined(__MINGW32__)
|
||||
|
|
@ -413,6 +416,18 @@ void V3Os::releaseMemory() {
|
|||
#ifdef HAVE_TCMALLOC
|
||||
MallocExtension::instance()->ReleaseFreeMemory();
|
||||
#endif
|
||||
#ifdef HAVE_JEMALLOC
|
||||
// Purge all unused dirty pages across all arenas
|
||||
unsigned narenas = 0;
|
||||
size_t sz = sizeof(narenas);
|
||||
if (mallctl("arenas.narenas", &narenas, &sz, nullptr, 0)) {
|
||||
return; // Failed to get number of arenas, give up
|
||||
}
|
||||
char buf[64];
|
||||
// Index equal to narenas represents all arenas
|
||||
VL_SNPRINTF(buf, sizeof(buf), "arena.%u.purge", narenas);
|
||||
mallctl(buf, nullptr, nullptr, nullptr, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
Loading…
Reference in New Issue