[BUG] Memory manager counts allocations not part of benchmark

Aperta Adatta ai principianti
#2,149 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
68/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
cpp
Ambito
performance

Direzione di ricerca

Inizia in src/benchmark_runner.cc, in BenchmarkRunner::RunMemoryManager, e confronta la configurazione e la pulizia delle risorse con le chiamate Start()/Stop() di MemoryManager. Riproduci il problema con un benchmark che non effettui allocazioni e un MemoryManager che riporti allocs_per_iter in JSON. Il lavoro è completato quando le allocazioni della configurazione sono escluse dall’intervallo misurato e le allocazioni della pulizia avvengono dopo Stop().

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Describe the bug

When using a MemoryManager, the Start() function is called before some more "internal" objects are created. This makes it impossible to get e.g. a 100% accurate allocation count.

When the call to the MemoryManager's Start() is made, other objects are created/allocated before the test is started. Here is e.g. RunMemoryManager from src/benchmark_runner.cc:

MemoryManager::Result BenchmarkRunner::RunMemoryManager(
    IterationCount memory_iterations) {
  memory_manager->Start();
  std::unique_ptr<internal::ThreadManager> manager;
  manager.reset(new internal::ThreadManager(1));
  b.Setup();
  RunInThread(&b, memory_iterations, 0, manager.get(),
              perf_counters_measurement_ptr,
              /*profiler_manager=*/nullptr);
  manager.reset();
  b.Teardown();
  MemoryManager::Result memory_result;
  memory_manager->Stop(memory_result);
  memory_result.memory_iterations = memory_iterations;
  return memory_result;
}

As is clear from the code, after calling MemoryManager::Start(), a new internal::ThreadManager object is created on the heap, and b.Setup() is called. Then, before MemoryManager::Stop() is called, manager.reset() and b.TearDown() are called.

IMHO both the internal::ThreadManager creation and the b.Setup()/b.Teardown() should happen before, respectively after, calling Start()/Stop(). That way only the memory use inside the for (auto _ : state) { ... } loop will be tracked, which is what I assume most people would be interested in.

I.e. I would have thought RunMemoryManager would have been implemented like this (note that memory_result is also moved in front of Start(), although it currently doesn't allocate):

MemoryManager::Result BenchmarkRunner::RunMemoryManager(
    IterationCount memory_iterations) {
  std::unique_ptr<internal::ThreadManager> manager;
  manager.reset(new internal::ThreadManager(1));
  b.Setup();
  MemoryManager::Result memory_result;
  memory_manager->Start();
  RunInThread(&b, memory_iterations, 0, manager.get(),
              perf_counters_measurement_ptr,
              /*profiler_manager=*/nullptr);
  memory_manager->Stop(memory_result);
  manager.reset();
  b.Teardown();
  memory_result.memory_iterations = memory_iterations;
  return memory_result;
}

System
Which OS, compiler, and compiler version are you using:

  • OS: Ubuntu 24.04 LTS
  • Compiler and version: GCC 12

To reproduce
Steps to reproduce the behavior:

  1. Implement MemoryManager that hooks malloc and friends
  2. Reset your MemoryManager's num_allocs in Start()
  3. Report your MemoryManager's num_allocs in Stop()
  4. Create a non-allocating benchmark (e.g. do nothing or fill an std::array)
  5. Run benchmark with --benchmark_format=json
  6. Notice how "allocs_per_iter" in the JSON is not zero
Lingua principale
C++
Stelle
10.4k
Fork
1.8k
Merge medio
2g 4h
PR unite (30g)
8

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di google/benchmark

Tutte le issue di google/benchmark

Issue simili

Altre issue su C++

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.