Skip to content

Commit ce77b41

Browse files
committed
integrate mimalloc
1 parent 7de1418 commit ce77b41

File tree

4 files changed

+146
-9
lines changed

4 files changed

+146
-9
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ option(RF_BUILD_APPS "Build applications in addition to library" ON)
1010
option(RF_BUILD_BINDINGS "Build python bindings with pybind" OFF)
1111
option(BUILD_SHARED_LIBS "Build using shared libraries (may not work)" OFF)
1212
option(RF_BUILD_TESTING "Enable tests for roofer" OFF)
13+
option(RF_ENABLE_HEAP_TRACING "Enable heap allocation overloads" OFF)
1314

1415
# Enable the vcpkg features that are required by the options
1516
if(RF_USE_LOGGER_SPDLOG)

apps/roofer-app/CMakeLists.txt

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
set(APP_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/roofer-app.cpp")
22

3+
find_package(mimalloc CONFIG REQUIRED)
4+
35
add_executable("roofer" ${APP_SOURCES})
46
set_target_properties("roofer" PROPERTIES CXX_STANDARD 20)
57
target_link_libraries("roofer" PRIVATE roofer-extra cmake_git_version_tracking
6-
fmt::fmt)
8+
fmt::fmt
9+
$<IF:$<TARGET_EXISTS:mimalloc-static>,mimalloc-static,mimalloc>)
710

811
# Used for getting the process memory usage
912
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
@@ -19,6 +22,9 @@ endif()
1922
if(RF_USE_VAL3DITY)
2023
target_compile_definitions("roofer" PRIVATE RF_USE_VAL3DITY)
2124
endif()
25+
if(RF_ENABLE_HEAP_TRACING)
26+
target_compile_definitions("roofer" PRIVATE RF_ENABLE_HEAP_TRACING)
27+
endif()
2228

2329
install(
2430
TARGETS "roofer"

apps/roofer-app/roofer-app.cpp

+133-8
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ namespace fs = std::filesystem;
7979
#include "git.h"
8080
#include "toml.hpp"
8181

82+
#include <mimalloc-override.h>
83+
8284
using fileExtent = std::pair<std::string, roofer::TBox<double>>;
8385

8486
struct InputPointcloud {
@@ -421,6 +423,7 @@ std::vector<roofer::TBox<double>> create_tiles(roofer::TBox<double>& roi,
421423
return tiles;
422424
}
423425

426+
#ifdef RF_ENABLE_HEAP_TRACING
424427
// Overrides for heap allocation counting
425428
// Ref.: https://www.youtube.com/watch?v=sLlGEUO_EGE
426429
namespace {
@@ -433,15 +436,133 @@ namespace {
433436
};
434437
HeapAllocationCounter heap_allocation_counter;
435438
} // namespace
439+
#endif
440+
441+
/*
442+
* Code snippet below is taken from
443+
* https://github.com/microsoft/mimalloc/blob/dev/include/mimalloc-new-delete.h
444+
* and modified to work with the roofer trace feature for heap memory usage.
445+
*/
446+
447+
#if defined(_MSC_VER) && defined(_Ret_notnull_) && \
448+
defined(_Post_writable_byte_size_)
449+
// stay consistent with VCRT definitions
450+
#define mi_decl_new(n) \
451+
mi_decl_nodiscard mi_decl_restrict _Ret_notnull_ _Post_writable_byte_size_(n)
452+
#define mi_decl_new_nothrow(n) \
453+
mi_decl_nodiscard mi_decl_restrict _Ret_maybenull_ _Success_(return != NULL) \
454+
_Post_writable_byte_size_(n)
455+
#else
456+
#define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict
457+
#define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict
458+
#endif
459+
460+
void operator delete(void* p) noexcept { mi_free(p); };
461+
void operator delete[](void* p) noexcept { mi_free(p); };
462+
463+
void operator delete(void* p, const std::nothrow_t&) noexcept { mi_free(p); }
464+
void operator delete[](void* p, const std::nothrow_t&) noexcept { mi_free(p); }
465+
466+
mi_decl_new(n) void* operator new(std::size_t n) noexcept(false) {
467+
#ifdef RF_ENABLE_HEAP_TRACING
468+
heap_allocation_counter.total_allocated += n;
469+
#endif
470+
return mi_new(n);
471+
}
472+
mi_decl_new(n) void* operator new[](std::size_t n) noexcept(false) {
473+
#ifdef RF_ENABLE_HEAP_TRACING
474+
heap_allocation_counter.total_allocated += n;
475+
#endif
476+
return mi_new(n);
477+
}
478+
479+
mi_decl_new_nothrow(n) void* operator new(std::size_t n,
480+
const std::nothrow_t& tag) noexcept {
481+
(void)(tag);
482+
#ifdef RF_ENABLE_HEAP_TRACING
483+
heap_allocation_counter.total_allocated += n;
484+
#endif
485+
return mi_new_nothrow(n);
486+
}
487+
mi_decl_new_nothrow(n) void* operator new[](
488+
std::size_t n, const std::nothrow_t& tag) noexcept {
489+
(void)(tag);
490+
#ifdef RF_ENABLE_HEAP_TRACING
491+
heap_allocation_counter.total_allocated += n;
492+
#endif
493+
return mi_new_nothrow(n);
494+
}
495+
496+
#if (__cplusplus >= 201402L || _MSC_VER >= 1916)
497+
void operator delete(void* p, std::size_t n) noexcept {
498+
#ifdef RF_ENABLE_HEAP_TRACING
499+
heap_allocation_counter.total_freed += n;
500+
#endif
501+
mi_free_size(p, n);
502+
};
503+
void operator delete[](void* p, std::size_t n) noexcept {
504+
#ifdef RF_ENABLE_HEAP_TRACING
505+
heap_allocation_counter.total_freed += n;
506+
#endif
507+
mi_free_size(p, n);
508+
};
509+
#endif
436510

437-
void* operator new(size_t size) {
438-
heap_allocation_counter.total_allocated += size;
439-
return malloc(size);
511+
#if (__cplusplus > 201402L || defined(__cpp_aligned_new))
512+
void operator delete(void* p, std::align_val_t al) noexcept {
513+
mi_free_aligned(p, static_cast<size_t>(al));
514+
}
515+
void operator delete[](void* p, std::align_val_t al) noexcept {
516+
mi_free_aligned(p, static_cast<size_t>(al));
440517
}
441-
void operator delete(void* memory, size_t size) noexcept {
442-
heap_allocation_counter.total_freed += size;
443-
free(memory);
518+
void operator delete(void* p, std::size_t n, std::align_val_t al) noexcept {
519+
#ifdef RF_ENABLE_HEAP_TRACING
520+
heap_allocation_counter.total_freed += n;
521+
#endif
522+
mi_free_size_aligned(p, n, static_cast<size_t>(al));
444523
};
524+
void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept {
525+
#ifdef RF_ENABLE_HEAP_TRACING
526+
heap_allocation_counter.total_freed += n;
527+
#endif
528+
mi_free_size_aligned(p, n, static_cast<size_t>(al));
529+
};
530+
void operator delete(void* p, std::align_val_t al,
531+
const std::nothrow_t&) noexcept {
532+
mi_free_aligned(p, static_cast<size_t>(al));
533+
}
534+
void operator delete[](void* p, std::align_val_t al,
535+
const std::nothrow_t&) noexcept {
536+
mi_free_aligned(p, static_cast<size_t>(al));
537+
}
538+
539+
void* operator new(std::size_t n, std::align_val_t al) noexcept(false) {
540+
#ifdef RF_ENABLE_HEAP_TRACING
541+
heap_allocation_counter.total_allocated += n;
542+
#endif
543+
return mi_new_aligned(n, static_cast<size_t>(al));
544+
}
545+
void* operator new[](std::size_t n, std::align_val_t al) noexcept(false) {
546+
#ifdef RF_ENABLE_HEAP_TRACING
547+
heap_allocation_counter.total_allocated += n;
548+
#endif
549+
return mi_new_aligned(n, static_cast<size_t>(al));
550+
}
551+
void* operator new(std::size_t n, std::align_val_t al,
552+
const std::nothrow_t&) noexcept {
553+
#ifdef RF_ENABLE_HEAP_TRACING
554+
heap_allocation_counter.total_allocated += n;
555+
#endif
556+
return mi_new_aligned_nothrow(n, static_cast<size_t>(al));
557+
}
558+
void* operator new[](std::size_t n, std::align_val_t al,
559+
const std::nothrow_t&) noexcept {
560+
#ifdef RF_ENABLE_HEAP_TRACING
561+
heap_allocation_counter.total_allocated += n;
562+
#endif
563+
return mi_new_aligned_nothrow(n, static_cast<size_t>(al));
564+
}
565+
#endif
445566

446567
/*
447568
* Author: David Robert Nadeau
@@ -688,7 +809,9 @@ int main(int argc, const char* argv[]) {
688809
tracer_thread.emplace([&] {
689810
while (crop_running.load() || reconstruction_running.load() ||
690811
serialization_running.load()) {
812+
#ifdef RF_ENABLE_HEAP_TRACING
691813
logger.trace("heap", heap_allocation_counter.current_usage());
814+
#endif
692815
logger.trace("rss", GetCurrentRSS());
693816
logger.trace("crop", cropped_buildings_cnt);
694817
logger.trace("reconstruct", reconstructed_buildings_cnt);
@@ -700,9 +823,11 @@ int main(int argc, const char* argv[]) {
700823
reconstructor_pool.get_tasks_queued());
701824
std::this_thread::sleep_for(trace_interval);
702825
}
703-
// We log once more after all threads have finished, to measure the finaly
704-
// memory use
826+
// We log once more after all threads have finished, to measure the finaly
827+
// memory use
828+
#ifdef RF_ENABLE_HEAP_TRACING
705829
logger.trace("heap", heap_allocation_counter.current_usage());
830+
#endif
706831
logger.trace("rss", GetCurrentRSS());
707832
logger.trace("crop", cropped_buildings_cnt);
708833
logger.trace("reconstruct", reconstructed_buildings_cnt);

vcpkg.json

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727
"dependencies": [
2828
"geos",
2929
"lastools",
30+
{
31+
"name": "mimalloc",
32+
"features": [
33+
]
34+
},
3035
{
3136
"name": "gdal",
3237
"features": [

0 commit comments

Comments
 (0)