refactor: migrate the only folly::Benchmark test to google-benchmark

This commit is contained in:
Marcus Holland-Moritz 2025-03-31 21:44:02 +02:00
parent 16e57a468b
commit 9eb5ca94b1
3 changed files with 88 additions and 156 deletions

View File

@ -585,15 +585,14 @@ if(WITH_LIBDWARFS AND WITH_BENCHMARKS)
target_link_libraries(nilsimsa_benchmark PRIVATE benchmark::benchmark) target_link_libraries(nilsimsa_benchmark PRIVATE benchmark::benchmark)
target_link_libraries(nilsimsa_benchmark PRIVATE dwarfs_writer) target_link_libraries(nilsimsa_benchmark PRIVATE dwarfs_writer)
list(APPEND BENCHMARK_TARGETS nilsimsa_benchmark) list(APPEND BENCHMARK_TARGETS nilsimsa_benchmark)
add_executable(segmenter_benchmark test/segmenter_benchmark.cpp)
target_link_libraries(segmenter_benchmark PRIVATE dwarfs_test_helpers benchmark::benchmark)
target_link_libraries(segmenter_benchmark PRIVATE dwarfs_writer)
list(APPEND BENCHMARK_TARGETS segmenter_benchmark)
list(APPEND BINARY_TARGETS ${BENCHMARK_TARGETS})
endif() endif()
# TODO: migrate to benchmark?
add_executable(segmenter_benchmark test/segmenter_benchmark.cpp)
target_link_libraries(segmenter_benchmark PRIVATE dwarfs_follybenchmark_lite dwarfs_test_helpers)
target_link_libraries(segmenter_benchmark PRIVATE dwarfs_writer)
list(APPEND BENCHMARK_TARGETS segmenter_benchmark)
list(APPEND BINARY_TARGETS ${BENCHMARK_TARGETS})
endif() endif()
if(WITH_LIBDWARFS AND WITH_FUZZ) if(WITH_LIBDWARFS AND WITH_FUZZ)

View File

@ -155,63 +155,7 @@ endif()
apply_folly_compile_options_to_target(dwarfs_folly_lite) apply_folly_compile_options_to_target(dwarfs_folly_lite)
target_link_libraries(dwarfs_folly_lite PUBLIC folly_deps) target_link_libraries(dwarfs_folly_lite PUBLIC folly_deps)
if(WITH_BENCHMARKS) foreach(tgt dwarfs_folly_lite)
add_library(dwarfs_follybenchmark_lite OBJECT
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/Benchmark.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/Format.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/SharedMutex.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/Unicode.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/concurrency/CacheLocality.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/detail/Futex.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/detail/PerfScoped.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/detail/StaticSingletonManager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/ext/test_ext.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/io/FsUtil.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/json/dynamic.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/json/json.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/json/json_pointer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/AsyncFileWriter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/AsyncLogWriter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/CustomLogFormatter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/FileWriterFactory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/GlogStyleFormatter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/ImmediateFileWriter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/LogCategory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/LogCategoryConfig.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/LogHandlerConfig.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/LogLevel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/LogMessage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/LogName.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/LogStream.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/LogStreamProcessor.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/LoggerDB.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/ObjectToString.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/RateLimiter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/StandardLogHandler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/StandardLogHandlerFactory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/StreamHandlerFactory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/logging/xlog.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/memory/ReentrantAllocator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/synchronization/ParkingLot.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/synchronization/SanitizeThread.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/system/AtFork.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/system/Pid.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/system/ThreadId.cpp
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/testing/TestUtil.cpp
)
if(NOT WIN32)
target_sources(dwarfs_follybenchmark_lite PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/folly/folly/Subprocess.cpp
)
endif()
set_property(TARGET dwarfs_follybenchmark_lite PROPERTY CXX_STANDARD 20)
apply_folly_compile_options_to_target(dwarfs_follybenchmark_lite)
target_link_libraries(dwarfs_follybenchmark_lite PUBLIC dwarfs_folly_lite)
find_package(Boost REQUIRED COMPONENTS regex)
target_link_libraries(dwarfs_follybenchmark_lite PUBLIC Boost::regex)
endif()
foreach(tgt dwarfs_folly_lite dwarfs_follybenchmark_lite)
if(TARGET ${tgt}) if(TARGET ${tgt})
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# See: https://github.com/cpp-best-practices/cppbestpractices/blob/master/02-Use_the_Tools_Available.md # See: https://github.com/cpp-best-practices/cppbestpractices/blob/master/02-Use_the_Tools_Available.md

View File

@ -22,7 +22,7 @@
#include <random> #include <random>
#include <vector> #include <vector>
#include <folly/Benchmark.h> #include <benchmark/benchmark.h>
#include <dwarfs/compression_constraints.h> #include <dwarfs/compression_constraints.h>
#include <dwarfs/writer/segmenter.h> #include <dwarfs/writer/segmenter.h>
@ -117,12 +117,10 @@ build_data(size_t total_size, size_t granularity, double dupe_fraction,
return data; return data;
} }
void run_segmenter_test(unsigned iters, unsigned granularity, void run_segmenter_benchmark(::benchmark::State& state, unsigned granularity,
unsigned window_size, unsigned block_size, unsigned window_size, unsigned block_size,
unsigned bloom_filter_size, unsigned lookback, unsigned bloom_filter_size, unsigned lookback,
double dupe_fraction) { double dupe_fraction) {
folly::BenchmarkSuspender suspender;
dwarfs::writer::segmenter::config cfg; dwarfs::writer::segmenter::config cfg;
cfg.blockhash_window_size = window_size; cfg.blockhash_window_size = window_size;
cfg.window_increment_shift = 1; cfg.window_increment_shift = 1;
@ -139,12 +137,14 @@ void run_segmenter_test(unsigned iters, unsigned granularity,
build_data(total_size, granularity, dupe_fraction, build_data(total_size, granularity, dupe_fraction,
{2 * granularity * (size_t(1) << window_size)})); {2 * granularity * (size_t(1) << window_size)}));
for (unsigned i = 0; i < iters; ++i) { std::vector<dwarfs::shared_byte_buffer> written;
size_t segmented{0};
for (auto _ : state) {
dwarfs::test::test_logger lgr; dwarfs::test::test_logger lgr;
dwarfs::writer::writer_progress prog; dwarfs::writer::writer_progress prog;
auto blkmgr = std::make_shared<dwarfs::writer::internal::block_manager>(); auto blkmgr = std::make_shared<dwarfs::writer::internal::block_manager>();
written.clear();
std::vector<dwarfs::shared_byte_buffer> written;
dwarfs::writer::segmenter seg( dwarfs::writer::segmenter seg(
lgr, prog, blkmgr, cfg, cc, total_size, lgr, prog, blkmgr, cfg, cc, total_size,
@ -155,22 +155,22 @@ void run_segmenter_test(unsigned iters, unsigned granularity,
blkmgr->set_written_block(logical_block_num, physical_block_num, 0); blkmgr->set_written_block(logical_block_num, physical_block_num, 0);
}); });
suspender.dismiss(); // begin benchmarking code
seg.add_chunkable(bc); seg.add_chunkable(bc);
seg.finish(); seg.finish();
suspender.rehire(); // end benchmarking code
size_t segmented [[maybe_unused]]{0};
for (auto const& blk : written) { for (auto const& blk : written) {
segmented += blk.size(); segmented += blk.size();
} }
// std::cerr << total_size << " -> " << segmented << fmt::format("
// ({:.1f}%)", 100.0*segmented/total_size) << std::endl;
} }
state.SetBytesProcessed(state.iterations() * total_size);
state.SetLabel(fmt::format(
"-- {:.1f} MiB -> {:.1f} MiB ({:.1f}%)", total_size / (1024.0 * 1024.0),
segmented / (1024.0 * 1024.0), 100.0 * segmented / total_size));
} }
constexpr unsigned const kDefaultGranularity{1}; constexpr unsigned const kDefaultGranularity{1};
@ -180,97 +180,86 @@ constexpr unsigned const kDefaultBloomFilterSize{4};
constexpr unsigned const kDefaultLookback{1}; constexpr unsigned const kDefaultLookback{1};
constexpr double const kDefaultDupeFraction{0.3}; constexpr double const kDefaultDupeFraction{0.3};
void run_granularity(unsigned iters, unsigned granularity) { template <unsigned Granularity>
run_segmenter_test(iters, granularity, kDefaultWindowSize, kDefaultBlockSize, void granularity(::benchmark::State& state) {
kDefaultBloomFilterSize, kDefaultLookback, run_segmenter_benchmark(state, Granularity, kDefaultWindowSize,
kDefaultDupeFraction); kDefaultBlockSize, kDefaultBloomFilterSize,
kDefaultLookback, kDefaultDupeFraction);
} }
void run_window_size(unsigned iters, unsigned window_size) { template <unsigned WindowSize>
run_segmenter_test(iters, kDefaultGranularity, window_size, kDefaultBlockSize, void window_size(::benchmark::State& state) {
kDefaultBloomFilterSize, kDefaultLookback, run_segmenter_benchmark(state, kDefaultGranularity, WindowSize,
kDefaultDupeFraction); kDefaultBlockSize, kDefaultBloomFilterSize,
kDefaultLookback, kDefaultDupeFraction);
} }
void run_block_size(unsigned iters, unsigned block_size) { template <unsigned BlockSize>
run_segmenter_test(iters, kDefaultGranularity, kDefaultWindowSize, block_size, void block_size(::benchmark::State& state) {
kDefaultBloomFilterSize, kDefaultLookback, run_segmenter_benchmark(state, kDefaultGranularity, kDefaultWindowSize,
kDefaultDupeFraction); BlockSize, kDefaultBloomFilterSize, kDefaultLookback,
kDefaultDupeFraction);
} }
void run_bloom_filter_size(unsigned iters, unsigned bloom_filter_size) { template <unsigned BloomFilterSize>
run_segmenter_test(iters, kDefaultGranularity, kDefaultWindowSize, void bloom_filter_size(::benchmark::State& state) {
kDefaultBlockSize, bloom_filter_size, kDefaultLookback, run_segmenter_benchmark(state, kDefaultGranularity, kDefaultWindowSize,
kDefaultDupeFraction); kDefaultBlockSize, BloomFilterSize, kDefaultLookback,
kDefaultDupeFraction);
} }
void run_lookback(unsigned iters, unsigned lookback) { template <unsigned Lookback>
run_segmenter_test(iters, kDefaultGranularity, kDefaultWindowSize, void lookback(::benchmark::State& state) {
kDefaultBlockSize, kDefaultBloomFilterSize, lookback, run_segmenter_benchmark(state, kDefaultGranularity, kDefaultWindowSize,
kDefaultDupeFraction); kDefaultBlockSize, kDefaultBloomFilterSize, Lookback,
kDefaultDupeFraction);
} }
void run_dupe_fraction(unsigned iters, unsigned dupe_fraction) { template <unsigned DupeFraction>
run_segmenter_test(iters, kDefaultGranularity, kDefaultWindowSize, void dupe_fraction(::benchmark::State& state) {
kDefaultBlockSize, kDefaultBloomFilterSize, run_segmenter_benchmark(state, kDefaultGranularity, kDefaultWindowSize,
kDefaultLookback, 0.01 * dupe_fraction); kDefaultBlockSize, kDefaultBloomFilterSize,
kDefaultLookback, 0.01 * DupeFraction);
} }
} // namespace } // namespace
BENCHMARK_DRAW_LINE(); BENCHMARK(granularity<1>)->Unit(benchmark::kMillisecond);
BENCHMARK(granularity<2>)->Unit(benchmark::kMillisecond);
BENCHMARK(granularity<3>)->Unit(benchmark::kMillisecond);
BENCHMARK(granularity<4>)->Unit(benchmark::kMillisecond);
BENCHMARK(granularity<5>)->Unit(benchmark::kMillisecond);
BENCHMARK(granularity<6>)->Unit(benchmark::kMillisecond);
BENCHMARK_PARAM(run_granularity, 1) BENCHMARK(window_size<8>)->Unit(benchmark::kMillisecond);
BENCHMARK_RELATIVE_PARAM(run_granularity, 2) BENCHMARK(window_size<10>)->Unit(benchmark::kMillisecond);
BENCHMARK_RELATIVE_PARAM(run_granularity, 3) BENCHMARK(window_size<12>)->Unit(benchmark::kMillisecond);
BENCHMARK_RELATIVE_PARAM(run_granularity, 4) BENCHMARK(window_size<14>)->Unit(benchmark::kMillisecond);
BENCHMARK_RELATIVE_PARAM(run_granularity, 5) BENCHMARK(window_size<16>)->Unit(benchmark::kMillisecond);
BENCHMARK_RELATIVE_PARAM(run_granularity, 6)
BENCHMARK_DRAW_LINE(); BENCHMARK(block_size<18>)->Unit(benchmark::kMillisecond);
BENCHMARK(block_size<20>)->Unit(benchmark::kMillisecond);
BENCHMARK(block_size<22>)->Unit(benchmark::kMillisecond);
BENCHMARK(block_size<24>)->Unit(benchmark::kMillisecond);
BENCHMARK(block_size<26>)->Unit(benchmark::kMillisecond);
BENCHMARK_PARAM(run_window_size, 8) BENCHMARK(bloom_filter_size<1>)->Unit(benchmark::kMillisecond);
BENCHMARK_RELATIVE_PARAM(run_window_size, 10) BENCHMARK(bloom_filter_size<2>)->Unit(benchmark::kMillisecond);
BENCHMARK_RELATIVE_PARAM(run_window_size, 12) BENCHMARK(bloom_filter_size<3>)->Unit(benchmark::kMillisecond);
BENCHMARK_RELATIVE_PARAM(run_window_size, 14) BENCHMARK(bloom_filter_size<4>)->Unit(benchmark::kMillisecond);
BENCHMARK_RELATIVE_PARAM(run_window_size, 16) BENCHMARK(bloom_filter_size<5>)->Unit(benchmark::kMillisecond);
BENCHMARK(bloom_filter_size<6>)->Unit(benchmark::kMillisecond);
BENCHMARK_DRAW_LINE(); BENCHMARK(lookback<1>)->Unit(benchmark::kMillisecond);
BENCHMARK(lookback<2>)->Unit(benchmark::kMillisecond);
BENCHMARK(lookback<4>)->Unit(benchmark::kMillisecond);
BENCHMARK(lookback<8>)->Unit(benchmark::kMillisecond);
BENCHMARK(lookback<16>)->Unit(benchmark::kMillisecond);
BENCHMARK_PARAM(run_block_size, 18) BENCHMARK(dupe_fraction<0>)->Unit(benchmark::kMillisecond);
BENCHMARK_RELATIVE_PARAM(run_block_size, 20) BENCHMARK(dupe_fraction<20>)->Unit(benchmark::kMillisecond);
BENCHMARK_RELATIVE_PARAM(run_block_size, 22) BENCHMARK(dupe_fraction<40>)->Unit(benchmark::kMillisecond);
BENCHMARK_RELATIVE_PARAM(run_block_size, 24) BENCHMARK(dupe_fraction<60>)->Unit(benchmark::kMillisecond);
BENCHMARK_RELATIVE_PARAM(run_block_size, 26) BENCHMARK(dupe_fraction<80>)->Unit(benchmark::kMillisecond);
BENCHMARK_DRAW_LINE(); BENCHMARK_MAIN();
BENCHMARK_PARAM(run_bloom_filter_size, 1)
BENCHMARK_RELATIVE_PARAM(run_bloom_filter_size, 2)
BENCHMARK_RELATIVE_PARAM(run_bloom_filter_size, 3)
BENCHMARK_RELATIVE_PARAM(run_bloom_filter_size, 4)
BENCHMARK_RELATIVE_PARAM(run_bloom_filter_size, 5)
BENCHMARK_RELATIVE_PARAM(run_bloom_filter_size, 6)
BENCHMARK_DRAW_LINE();
BENCHMARK_PARAM(run_lookback, 1)
BENCHMARK_RELATIVE_PARAM(run_lookback, 2)
BENCHMARK_RELATIVE_PARAM(run_lookback, 4)
BENCHMARK_RELATIVE_PARAM(run_lookback, 8)
BENCHMARK_RELATIVE_PARAM(run_lookback, 16)
BENCHMARK_DRAW_LINE();
BENCHMARK_PARAM(run_dupe_fraction, 0)
BENCHMARK_RELATIVE_PARAM(run_dupe_fraction, 20)
BENCHMARK_RELATIVE_PARAM(run_dupe_fraction, 40)
BENCHMARK_RELATIVE_PARAM(run_dupe_fraction, 60)
BENCHMARK_RELATIVE_PARAM(run_dupe_fraction, 80)
BENCHMARK_DRAW_LINE();
int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
folly::runBenchmarks();
}