Skip to content

Commit 430020d

Browse files
committed
fix: keep benchmark root across warm iterations
1 parent 1ba3a2b commit 430020d

1 file changed

Lines changed: 139 additions & 32 deletions

File tree

port/linux/benchmark/main.cpp

Lines changed: 139 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,14 @@ static void function_call_starred_1000(benchmark::State& state) {
185185
}
186186
BENCHMARK(function_call_starred_1000)->Unit(benchmark::kMillisecond);
187187

188+
static const char* fibonacci_source =
189+
"def fib(n):\n"
190+
" if n < 2:\n"
191+
" return n\n"
192+
" return fib(n - 1) + fib(n - 2)\n"
193+
"result = fib(20)\n"
194+
"\n";
195+
188196
static void fibonacci_recursive_20(benchmark::State& state) {
189197
using clock = std::chrono::steady_clock;
190198
auto nanoseconds = [](clock::duration duration) {
@@ -193,76 +201,175 @@ static void fibonacci_recursive_20(benchmark::State& state) {
193201
};
194202
auto compile_start = clock::now();
195203
Args* buffs = New_strBuff();
196-
char* pikaAsm = pika_lines2Asm(
197-
buffs, (char*)
198-
"def fib(n):\n"
199-
" if n < 2:\n"
200-
" return n\n"
201-
" return fib(n - 1) + fib(n - 2)\n"
202-
"result = fib(20)\n"
203-
"\n");
204+
char* pikaAsm = pika_lines2Asm(buffs, (char*)fibonacci_source);
204205
ByteCodeFrame bytecode_frame;
205206
byteCodeFrame_init(&bytecode_frame);
206207
byteCodeFrame_appendFromAsm(&bytecode_frame, pikaAsm);
207208
auto compile_end = clock::now();
208-
uint64_t root_create_ns = 0;
209+
210+
pikaMemAllocationCountReset();
211+
auto root_create_start = clock::now();
212+
PikaObj* pikaMain = newRootObj((char*)"pikaMain", New_PikaMain);
213+
auto root_create_end = clock::now();
214+
uint64_t root_create_allocations = pikaMemAllocationCount();
215+
uint32_t warm_heap_baseline_bytes = pikaMemNow();
216+
209217
uint64_t execute_ns = 0;
218+
uint64_t execute_allocations = 0;
219+
pikaMemMaxReset();
220+
pikaMemAllocationCountReset();
221+
for (auto _ : state) {
222+
uint32_t before_execute_allocations = pikaMemAllocationCount();
223+
auto execute_start = clock::now();
224+
pikaVM_runByteCodeFrame(pikaMain, &bytecode_frame);
225+
auto execute_end = clock::now();
226+
execute_allocations +=
227+
pikaMemAllocationCount() - before_execute_allocations;
228+
if (6765 != obj_getInt(pikaMain, (char*)"result")) {
229+
state.SkipWithError("recursive fibonacci result mismatch");
230+
}
231+
execute_ns += nanoseconds(execute_end - execute_start);
232+
}
233+
uint32_t heap_peak_bytes = pikaMemMax();
234+
uint32_t before_destroy_allocations = pikaMemAllocationCount();
235+
auto root_destroy_start = clock::now();
236+
obj_deinit(pikaMain);
237+
auto root_destroy_end = clock::now();
238+
uint64_t root_destroy_allocations =
239+
pikaMemAllocationCount() - before_destroy_allocations;
240+
byteCodeFrame_deinit(&bytecode_frame);
241+
args_deinit(buffs);
242+
243+
state.counters["compile_once_ns"] =
244+
nanoseconds(compile_end - compile_start);
245+
state.counters["setup_root_create_ns"] =
246+
nanoseconds(root_create_end - root_create_start);
247+
state.counters["warm_execute_ns"] = benchmark::Counter(
248+
execute_ns, benchmark::Counter::kAvgIterations);
249+
state.counters["teardown_root_destroy_ns"] =
250+
nanoseconds(root_destroy_end - root_destroy_start);
251+
state.counters["setup_root_create_allocations"] =
252+
root_create_allocations;
253+
state.counters["execute_allocations"] = benchmark::Counter(
254+
execute_allocations, benchmark::Counter::kAvgIterations);
255+
state.counters["teardown_root_destroy_allocations"] =
256+
root_destroy_allocations;
257+
state.counters["heap_allocations"] = benchmark::Counter(
258+
execute_allocations, benchmark::Counter::kAvgIterations);
259+
state.counters["heap_peak_bytes"] = heap_peak_bytes;
260+
state.counters["warm_heap_baseline_bytes"] =
261+
warm_heap_baseline_bytes;
262+
state.counters["heap_residual_bytes"] = pikaMemNow();
263+
state.counters["root_destroy_count"] = 1;
264+
}
265+
BENCHMARK(fibonacci_recursive_20)->Unit(benchmark::kMillisecond);
266+
267+
static void fibonacci_recursive_20_cold_start(benchmark::State& state) {
268+
using clock = std::chrono::steady_clock;
269+
auto nanoseconds = [](clock::duration duration) {
270+
return std::chrono::duration_cast<std::chrono::nanoseconds>(duration)
271+
.count();
272+
};
273+
uint64_t root_create_ns = 0;
274+
uint64_t compile_ns = 0;
275+
uint64_t first_execute_ns = 0;
210276
uint64_t root_destroy_ns = 0;
277+
uint64_t cleanup_ns = 0;
211278
uint64_t root_create_allocations = 0;
279+
uint64_t compile_allocations = 0;
212280
uint64_t execute_allocations = 0;
213-
uint64_t root_destroy_allocations = 0;
281+
uint64_t destroy_allocations = 0;
282+
uint64_t cleanup_allocations = 0;
214283
uint32_t heap_peak_bytes = 0;
284+
uint32_t heap_residual_bytes = 0;
285+
215286
for (auto _ : state) {
216287
pikaMemMaxReset();
217288
pikaMemAllocationCountReset();
289+
218290
auto root_create_start = clock::now();
219291
PikaObj* pikaMain = newRootObj((char*)"pikaMain", New_PikaMain);
220292
auto root_create_end = clock::now();
221-
root_create_allocations += pikaMemAllocationCount();
222-
uint32_t before_execute_allocations = pikaMemAllocationCount();
293+
uint32_t after_root_allocations = pikaMemAllocationCount();
294+
295+
auto compile_start = clock::now();
296+
Args* buffs = New_strBuff();
297+
char* pikaAsm = pika_lines2Asm(buffs, (char*)fibonacci_source);
298+
ByteCodeFrame bytecode_frame;
299+
byteCodeFrame_init(&bytecode_frame);
300+
byteCodeFrame_appendFromAsm(&bytecode_frame, pikaAsm);
301+
auto compile_end = clock::now();
302+
uint32_t after_compile_allocations = pikaMemAllocationCount();
303+
223304
auto execute_start = clock::now();
224305
pikaVM_runByteCodeFrame(pikaMain, &bytecode_frame);
225306
auto execute_end = clock::now();
226-
execute_allocations +=
227-
pikaMemAllocationCount() - before_execute_allocations;
307+
uint32_t after_execute_allocations = pikaMemAllocationCount();
228308
if (6765 != obj_getInt(pikaMain, (char*)"result")) {
229-
state.SkipWithError("recursive fibonacci result mismatch");
309+
state.SkipWithError("cold fibonacci result mismatch");
230310
}
231-
uint32_t before_destroy_allocations = pikaMemAllocationCount();
311+
232312
auto root_destroy_start = clock::now();
233313
obj_deinit(pikaMain);
234314
auto root_destroy_end = clock::now();
235-
root_destroy_allocations +=
236-
pikaMemAllocationCount() - before_destroy_allocations;
237-
root_create_ns += nanoseconds(root_create_end - root_create_start);
238-
execute_ns += nanoseconds(execute_end - execute_start);
239-
root_destroy_ns += nanoseconds(root_destroy_end - root_destroy_start);
315+
uint32_t after_destroy_allocations = pikaMemAllocationCount();
316+
317+
auto cleanup_start = clock::now();
318+
byteCodeFrame_deinit(&bytecode_frame);
319+
args_deinit(buffs);
320+
auto cleanup_end = clock::now();
321+
uint32_t after_cleanup_allocations = pikaMemAllocationCount();
322+
323+
root_create_ns +=
324+
nanoseconds(root_create_end - root_create_start);
325+
compile_ns += nanoseconds(compile_end - compile_start);
326+
first_execute_ns += nanoseconds(execute_end - execute_start);
327+
root_destroy_ns +=
328+
nanoseconds(root_destroy_end - root_destroy_start);
329+
cleanup_ns += nanoseconds(cleanup_end - cleanup_start);
330+
root_create_allocations += after_root_allocations;
331+
compile_allocations +=
332+
after_compile_allocations - after_root_allocations;
333+
execute_allocations +=
334+
after_execute_allocations - after_compile_allocations;
335+
destroy_allocations +=
336+
after_destroy_allocations - after_execute_allocations;
337+
cleanup_allocations +=
338+
after_cleanup_allocations - after_destroy_allocations;
240339
heap_peak_bytes = std::max(heap_peak_bytes, pikaMemMax());
340+
heap_residual_bytes = std::max(heap_residual_bytes, pikaMemNow());
241341
}
242-
byteCodeFrame_deinit(&bytecode_frame);
243-
args_deinit(buffs);
244-
state.counters["compile_once_ns"] =
245-
nanoseconds(compile_end - compile_start);
342+
246343
state.counters["root_create_ns"] = benchmark::Counter(
247344
root_create_ns, benchmark::Counter::kAvgIterations);
248-
state.counters["execute_ns"] = benchmark::Counter(
249-
execute_ns, benchmark::Counter::kAvgIterations);
345+
state.counters["compile_ns"] = benchmark::Counter(
346+
compile_ns, benchmark::Counter::kAvgIterations);
347+
state.counters["first_execute_ns"] = benchmark::Counter(
348+
first_execute_ns, benchmark::Counter::kAvgIterations);
250349
state.counters["root_destroy_ns"] = benchmark::Counter(
251350
root_destroy_ns, benchmark::Counter::kAvgIterations);
351+
state.counters["cleanup_ns"] = benchmark::Counter(
352+
cleanup_ns, benchmark::Counter::kAvgIterations);
252353
state.counters["root_create_allocations"] = benchmark::Counter(
253354
root_create_allocations, benchmark::Counter::kAvgIterations);
355+
state.counters["compile_allocations"] = benchmark::Counter(
356+
compile_allocations, benchmark::Counter::kAvgIterations);
254357
state.counters["execute_allocations"] = benchmark::Counter(
255358
execute_allocations, benchmark::Counter::kAvgIterations);
256359
state.counters["root_destroy_allocations"] = benchmark::Counter(
257-
root_destroy_allocations, benchmark::Counter::kAvgIterations);
360+
destroy_allocations, benchmark::Counter::kAvgIterations);
361+
state.counters["cleanup_allocations"] = benchmark::Counter(
362+
cleanup_allocations, benchmark::Counter::kAvgIterations);
258363
state.counters["heap_allocations"] = benchmark::Counter(
259-
root_create_allocations + execute_allocations +
260-
root_destroy_allocations,
364+
root_create_allocations + compile_allocations +
365+
execute_allocations + destroy_allocations +
366+
cleanup_allocations,
261367
benchmark::Counter::kAvgIterations);
262368
state.counters["heap_peak_bytes"] = heap_peak_bytes;
263-
state.counters["heap_residual_bytes"] = pikaMemNow();
369+
state.counters["heap_residual_bytes"] = heap_residual_bytes;
264370
}
265-
BENCHMARK(fibonacci_recursive_20)->Unit(benchmark::kMillisecond);
371+
BENCHMARK(fibonacci_recursive_20_cold_start)
372+
->Unit(benchmark::kMillisecond);
266373

267374
static void embedded_control_loop_1000(benchmark::State& state) {
268375
Args* buffs = New_strBuff();

0 commit comments

Comments
 (0)