Skip to content

Commit 92b3837

Browse files
committed
add WITH_MALLOC_TUNING CMake option (default ON)
Make the process-wide allocator tuning introduced in #1213 opt-out via a new build flag, since it changes malloc policy for the whole host application (freed memory is retained in-process, raising resident set size for workloads with large transient peaks). - Gate the glibc mallopt(M_MMAP_MAX=0, M_TRIM_THRESHOLD=-1) startup tuning behind WITH_MALLOC_TUNING and propagate the flag through config_core.h; build with -DWITH_MALLOC_TUNING=OFF to disable. - Document per-platform behavior in explicit branches: macOS libmalloc already retains freed memory (madvise-reusable pages plus the large cache), and the Windows process heap exposes no retention knob. - Rewrite the __APPLE__ branch of AllocTrim() to use the supported malloc_zone_pressure_relief(NULL, 0) all-zones call instead of the malloc_get_all_zones()/mach introspection API, dropping <mach/mach.h>. - Docs: add the new flag and the previously undocumented options (GIT_SUBMOD_AUTO, WITH_COVTEST, WITH_NOISE_DEBUG, WITH_REDUCED_NOISE, USE_MACPORTS) to the CMake flags table, and fix stale defaults (WITH_BE2 is OFF; the default math backend is 4, not 2).
1 parent dcf4952 commit 92b3837

4 files changed

Lines changed: 58 additions & 40 deletions

File tree

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ option(WITH_BE2 "Include MATHBACKEND 2 in build by setting WITH_BE2 to ON"
8888
option(WITH_BE4 "Include MATHBACKEND 4 in build by setting WITH_BE4 to ON" OFF )
8989
option(WITH_NTL "Include MATHBACKEND 6 and NTL in build by setting WITH_NTL to ON" OFF )
9090
option(WITH_TCM "Activate tcmalloc by setting WITH_TCM to ON" OFF )
91+
option(WITH_MALLOC_TUNING "Tune glibc malloc to retain freed memory for reuse" ON )
9192
option(WITH_NATIVEOPT "Use machine-specific optimizations" OFF )
9293
option(WITH_COVTEST "Turn on to enable coverage testing (can be used with g++ only)" OFF )
9394
option(WITH_NOISE_DEBUG "Use only when running lattice estimator; not for production" OFF )
@@ -115,6 +116,7 @@ message(STATUS "WITH_BE2: ${WITH_BE2}")
115116
message(STATUS "WITH_BE4: ${WITH_BE4}")
116117
message(STATUS "WITH_NTL: ${WITH_NTL}")
117118
message(STATUS "WITH_TCM: ${WITH_TCM}")
119+
message(STATUS "WITH_MALLOC_TUNING: ${WITH_MALLOC_TUNING}")
118120
message(STATUS "WITH_OPENMP: ${WITH_OPENMP}")
119121
message(STATUS "NATIVE_SIZE: ${NATIVE_SIZE}")
120122
message(STATUS "CKKS_M_FACTOR: ${CKKS_M_FACTOR}")

configure/config_core.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#cmakedefine WITH_REDUCED_NOISE
1111
#cmakedefine WITH_NTL
1212
#cmakedefine WITH_TCM
13+
#cmakedefine WITH_MALLOC_TUNING
1314
#cmakedefine WITH_OPENMP
1415
#cmakedefine WITH_NATIVEOPT
1516

docs/sphinx_rsts/intro/installation/cmake_in_openfhe.rst

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -81,28 +81,34 @@ Each of the options is enabled by saying ``-DOPTION_NAME=ON`` and is disabled by
8181

8282
The table below shows the current list of options, definition for the option, and a default value.
8383

84-
================== ===================================================================================================================================================================== ==========
85-
OPTION_NAME Description Default
86-
================== ===================================================================================================================================================================== ==========
87-
BUILD_UNITTESTS Set to ON to build unit tests for the library ON
88-
BUILD_EXAMPLES Set to ON to build examples for the library ON
89-
BUILD_BENCHMARKS Set to ON to build benchmarks for the library ON
90-
BUILD_EXTRAS Set to ON to build extra examples for the library OFF
91-
BUILD_SHARED Set to ON to include shared versions of the library ON
92-
BUILD_STATIC Set to ON to include static versions of the library OFF
93-
WITH_BE2 Include Backend 2 in build by setting WITH_BE2 to ON ON
94-
WITH_BE4 Include Backend 4 in build by setting WITH_BE4 to ON ON
95-
WITH_NTL Include Backend 6 and NTL in build by setting WITH_NTL to ON OFF
96-
WITH_TCM Activate tcmalloc by setting WITH_TCM to ON OFF
97-
WITH_OPENMP Use OpenMP to enable <omp.h> ON
98-
WITH_NATIVEOPT Use machine-specific optimizations (major speedup for clang) OFF
99-
NATIVE_SIZE Set default word size for native integer arithmetic to 64 or 128 bits 64
100-
CKKS_M_FACTOR Parameter used to strengthen the CKKS adversarial model in scenarios where decryption results are shared among multiple parties (See Security.md for more details) 1
101-
================== ===================================================================================================================================================================== ==========
84+
==================== ===================================================================================================================================================================== ==========
85+
OPTION_NAME Description Default
86+
==================== ===================================================================================================================================================================== ==========
87+
BUILD_UNITTESTS Set to ON to build unit tests for the library ON
88+
BUILD_EXAMPLES Set to ON to build examples for the library ON
89+
BUILD_BENCHMARKS Set to ON to build benchmarks for the library ON
90+
BUILD_EXTRAS Set to ON to build extra examples for the library OFF
91+
BUILD_SHARED Set to ON to include shared versions of the library ON
92+
BUILD_STATIC Set to ON to include static versions of the library OFF
93+
GIT_SUBMOD_AUTO Automatically update git submodules at CMake configure time ON
94+
WITH_BE2 Include Backend 2 in build by setting WITH_BE2 to ON OFF
95+
WITH_BE4 Include Backend 4 in build by setting WITH_BE4 to ON (always ON when MATHBACKEND=4, the default) ON
96+
WITH_NTL Include Backend 6 and NTL in build by setting WITH_NTL to ON OFF
97+
WITH_TCM Activate tcmalloc by setting WITH_TCM to ON OFF
98+
WITH_MALLOC_TUNING Tune glibc malloc to retain freed memory for reuse (higher performance, higher resident memory; see AllocTrim()) ON
99+
WITH_OPENMP Use OpenMP to enable <omp.h> ON
100+
WITH_NATIVEOPT Use machine-specific optimizations (major speedup for clang) OFF
101+
WITH_COVTEST Turn on to enable coverage testing (can be used with g++ only) OFF
102+
WITH_NOISE_DEBUG Use only when running the lattice estimator; not for production OFF
103+
WITH_REDUCED_NOISE Enable reduced noise within HKS and BFV HPSPOVERQ modes OFF
104+
USE_MACPORTS Use MacPorts installed packages (macOS) OFF
105+
NATIVE_SIZE Set default word size for native integer arithmetic to 64 or 128 bits 64
106+
CKKS_M_FACTOR Parameter used to strengthen the CKKS adversarial model in scenarios where decryption results are shared among multiple parties (See Security.md for more details) 1
107+
==================== ===================================================================================================================================================================== ==========
102108

103109
.. note:: More Options will be added as development progresses
104110

105-
The default math backend for the OpenFHE build is Backend 2 (basic fixed-maximum-length big integers). This default can be changed on the CMake command line by setting the MATHBACKEND variable. For example, to select backend 6 (high performance fixed integers based on the GMP and NTL libraries), use ``-DMATHBACKEND=6`` on the CMake command line.
111+
The default math backend for the OpenFHE build is Backend 4 (dynamically-sized big integers). This default can be changed on the CMake command line by setting the MATHBACKEND variable. For example, to select backend 6 (high performance fixed integers based on the GMP and NTL libraries), use ``-DMATHBACKEND=6`` on the CMake command line.
106112

107113
Detecting Local Environments
108114
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/core/lib/utils/memory.cpp

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@
2828
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2929
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3030
//==================================================================================
31+
32+
#include "config_core.h"
3133
#include "utils/memory.h"
3234

3335
#if defined(__APPLE__)
34-
#include <mach/mach.h>
3536
#include <malloc/malloc.h>
3637
#elif defined(__GLIBC__)
3738
#include <malloc.h>
@@ -41,22 +42,36 @@
4142

4243
namespace lbcrypto {
4344

44-
#if defined(__GLIBC__)
45-
// Tune glibc malloc for FHE allocation patterns. Each homomorphic operation allocates and
46-
// frees many large (~0.5-30 MB) polynomial coefficient buffers. By default glibc returns
47-
// these freed buffers to the OS (brk heap-trim / munmap) and re-faults the pages on the next
48-
// operation; under a single thread this page-fault / kernel-time overhead can dominate
49-
// runtime. Keeping large allocations on the heap (M_MMAP_MAX=0) and never trimming it back to
50-
// the OS (M_TRIM_THRESHOLD=-1) lets the buffers be reused, eliminating the churn. Runs once,
51-
// process-wide, at library load. NOTE: this retains freed memory in-process, so workloads
52-
// with large transient allocation peaks will show a higher resident set size. Use AllocTrim()
53-
// after large allocations are freed if this becomes an issue.
45+
#if defined(WITH_MALLOC_TUNING)
46+
// Tune the process allocator to retain freed memory for reuse. OpenFHE operations allocate and
47+
// free many large (~0.5-30 MB) buffers; on allocators that return freed buffers to the OS right
48+
// away, re-faulting the pages on the next operation can dominate single-threaded runtime. Any
49+
// tuning below runs once, process-wide, at library load. NOTE: retained memory shows up as a
50+
// higher resident set size for workloads with large transient allocation peaks. Use AllocTrim()
51+
// after large allocations are freed if this becomes an issue, or build with
52+
// -DWITH_MALLOC_TUNING=OFF to disable this tuning entirely.
5453
namespace {
54+
#if defined(__APPLE__)
55+
// Nothing to tune: macOS libmalloc already retains freed memory in-process. Freed pages of
56+
// small/medium allocations stay mapped and are marked reusable (the kernel reclaims them only
57+
// under memory pressure), and freed large allocations are held in the default zone's cache.
58+
// There is no public API to tune this behavior further; AllocTrim() releases these caches.
59+
#elif defined(__GLIBC__)
60+
// By default glibc returns freed large buffers to the OS (brk heap-trim / munmap) and re-faults
61+
// the pages on the next operation. Keeping large allocations on the heap (M_MMAP_MAX=0) and
62+
// never trimming it back to the OS (M_TRIM_THRESHOLD=-1) lets the buffers be reused,
63+
// eliminating the churn.
5564
[[maybe_unused]] const bool ofheGlibcMallocTuned = []() noexcept {
5665
mallopt(M_MMAP_MAX, 0);
5766
mallopt(M_TRIM_THRESHOLD, -1);
5867
return true;
5968
}();
69+
#elif defined(_MSC_VER)
70+
// Nothing to tune: the CRT heap is the Windows process heap, which serves allocations above
71+
// roughly 0.5-1 MB directly via VirtualAlloc and returns them to the OS on free, with no
72+
// supported process-wide switch to retain them. If this churn matters, link a caching
73+
// allocator (e.g. mimalloc or tcmalloc) instead.
74+
#endif
6075
} // namespace
6176
#endif
6277

@@ -73,15 +88,7 @@ namespace {
7388
// never from a signal handler. Returns true if a trim was attempted, false on unsupported builds.
7489
bool AllocTrim() {
7590
#if defined(__APPLE__)
76-
vm_address_t* zones = nullptr;
77-
unsigned count = 0;
78-
if (malloc_get_all_zones(mach_task_self(), nullptr, &zones, &count) == KERN_SUCCESS && zones) {
79-
for (unsigned i = 0; i < count; ++i) {
80-
auto* z = reinterpret_cast<malloc_zone_t*>(zones[i]);
81-
if (z)
82-
malloc_zone_pressure_relief(z, 0);
83-
}
84-
}
91+
malloc_zone_pressure_relief(nullptr, 0);
8592
return true;
8693
#elif defined(__GLIBC__)
8794
malloc_trim(0);
@@ -94,8 +101,10 @@ bool AllocTrim() {
94101
#endif
95102
}
96103

104+
// secure_memset() overwrites memory with c and, unlike a plain std::memset() of an object about
105+
// to be freed or go out of scope, is guaranteed not to be removed by dead-store elimination.
97106
void secure_memset(volatile void* mem, uint8_t c, size_t len) {
98-
volatile uint8_t* ptr = (volatile uint8_t*)mem;
107+
volatile uint8_t* ptr = static_cast<volatile uint8_t*>(mem);
99108
for (size_t i = 0; i < len; ++i)
100109
*(ptr + i) = c;
101110
}

0 commit comments

Comments
 (0)