Skip to content

Growing virtual memory usage on multithreaded benchmark #806

@jmftrindade

Description

@jmftrindade

Hi, there! It looks like on multithreaded benchmarks virtual memory keeps growing and is never freed. Valgrind only shows a leak of 240 bytes due to #782 so not sure why virtual mem only keeps growing. Also, I only see this on multithreaded benchmarks.

For example, on this bench below, which just adds numbers to a vector<uint64_t>, virtual mem quickly gets to upwards of 60GB and never seems to get freed in between benchmark runs:

#include <vector>

#include "benchmark/benchmark.h"

namespace bench {

const int kBMRangeMultiplier = 10;
const int kBMRangeLower = 1000;
const int kBMRangeUpper = 500000000;

static void BM_MemGrowthMultithreaded(benchmark::State& state) {
  std::vector<uint64_t> numbers;
  numbers.reserve(state.range(0));
  for (int i = 0; i < state.range(0); ++i) {
    numbers.push_back(i);
  }

  for (auto _ : state) {
    size_t size = state.range(0);
    std::vector<uint64_t> results;
    results.reserve(size);

    // It doesn't matter what we're adding, just creating some load.
    for (size_t i = 0; i < size; i++) {
      results.push_back(i);
    }

    state.counters["matches"] =
        benchmark::Counter(results.size(), benchmark::Counter::kAvgThreads);
  }

  state.SetComplexityN(state.range(0));
}
// Single-threaded.
BENCHMARK(BM_MemGrowthMultithreaded)
    ->Threads(1)
    ->UseRealTime()
    ->RangeMultiplier(kBMRangeMultiplier)
    ->Range(kBMRangeLower, kBMRangeUpper)
    ->Unit(benchmark::kMillisecond)
    ->Complexity(benchmark::oN);

// 2 threads.
BENCHMARK(BM_MemGrowthMultithreaded)
    ->Threads(2)
    ->UseRealTime()
    ->RangeMultiplier(kBMRangeMultiplier)
    ->Range(kBMRangeLower, kBMRangeUpper)
    ->Unit(benchmark::kMillisecond)
    ->Complexity(benchmark::oN);

// 4 threads.
BENCHMARK(BM_MemGrowthMultithreaded)
    ->Threads(4)
    ->UseRealTime()
    ->RangeMultiplier(kBMRangeMultiplier)
    ->Range(kBMRangeLower, kBMRangeUpper)
    ->Unit(benchmark::kMillisecond)
    ->Complexity(benchmark::oN);

// 8 threads.
BENCHMARK(BM_MemGrowthMultithreaded)
    ->Threads(8)
    ->UseRealTime()
    ->RangeMultiplier(kBMRangeMultiplier)
    ->Range(kBMRangeLower, kBMRangeUpper)
    ->Unit(benchmark::kMillisecond)
    ->Complexity(benchmark::oN);

}  // namespace bench

BENCHMARK_MAIN();

Is this expected behavior? Thanks! --Joana

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions