Skip to content

Commit a8b65f4

Browse files
committed
Add simple benchmark for alternative VM calls
1 parent 16b4a27 commit a8b65f4

File tree

1 file changed

+68
-2
lines changed

1 file changed

+68
-2
lines changed

src/bench.cpp

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ static constexpr bool FULL_RESET = true;
2121
inline timespec time_now();
2222
inline long nanodiff(timespec start_time, timespec end_time);
2323
static long micro_benchmark(std::function<void()>);
24+
static void benchmark_alternate_tenant_vmcalls(tinykvm::Machine &, size_t);
2425
static void benchmark_alternate_tenant_resets(tinykvm::Machine &, size_t);
2526
static void benchmark_multiple_vms(tinykvm::Machine&, size_t, size_t);
2627
static void benchmark_multiple_pooled_vms(tinykvm::Machine&, size_t, size_t);
@@ -393,6 +394,9 @@ int main(int argc, char** argv)
393394
printf("Fast reset: %ldns (%ld micros)\n", frtime, frtime / 1000);
394395
printf("Fast vmcall: %ldns (%ld micros)\n", frcall, frcall / 1000);
395396

397+
// Benchmark alternating vmcalls on two different VMs
398+
benchmark_alternate_tenant_vmcalls(master_vm, 500000);
399+
396400
// This benchmark mixes different VMs on the same thread,
397401
// which is supported, but has a serious penalty on Linux.
398402
benchmark_alternate_tenant_resets(master_vm, 5000);
@@ -420,6 +424,68 @@ int main(int argc, char** argv)
420424
benchmark_multiple_pooled_vms(master_vm, 64, 15000);
421425
}
422426

427+
void benchmark_alternate_tenant_vmcalls(tinykvm::Machine& master_vm, const size_t iterations)
428+
{
429+
// Make a full copy of the main VM into other_vm
430+
tinykvm::Machine vm1 { binary,
431+
{
432+
.max_mem = GUEST_MEMORY,
433+
.max_cow_mem = 0
434+
} };
435+
vm1.setup_linux(
436+
{"kvmtest", "Hello World!\n"},
437+
{"LC_TYPE=C", "LC_ALL=C", "USER=root"});
438+
vm1.run();
439+
440+
tinykvm::Machine vm2 { binary,
441+
{
442+
.max_mem = GUEST_MEMORY,
443+
.max_cow_mem = 0
444+
} };
445+
vm2.setup_linux(
446+
{"kvmtest", "Hello World!\n"},
447+
{"LC_TYPE=C", "LC_ALL=C", "USER=root"});
448+
vm2.run();
449+
450+
const uint64_t vmcall_address = vm1.address_of("bench");
451+
assert(vmcall_address == vm2.address_of("bench"));
452+
453+
/* Reset benchmark */
454+
uint64_t frcall1 = 0;
455+
uint64_t frcall2 = 0;
456+
long max_call1 = 0;
457+
long max_call2 = 0;
458+
459+
for (unsigned i = 0; i < 100; i++) {
460+
vm1.timed_vmcall(vmcall_address, 4.0f);
461+
vm2.timed_vmcall(vmcall_address, 4.0f);
462+
}
463+
464+
for (unsigned i = 0; i < iterations; i++)
465+
{
466+
auto frt0 = time_now();
467+
asm("" : : : "memory");
468+
vm1.timed_vmcall(vmcall_address, 4.0f);
469+
asm("" : : : "memory");
470+
auto frt1 = time_now();
471+
asm("" : : : "memory");
472+
vm2.timed_vmcall(vmcall_address, 4.0f);
473+
asm("" : : : "memory");
474+
auto frt2 = time_now();
475+
frcall1 += nanodiff(frt0, frt1);
476+
frcall2 += nanodiff(frt1, frt2);
477+
max_call1 = std::max(max_call1, nanodiff(frt0, frt1));
478+
max_call2 = std::max(max_call2, nanodiff(frt1, frt2));
479+
}
480+
frcall1 /= iterations;
481+
frcall2 /= iterations;
482+
483+
printf("Alternating vmcall VM1: %ldns, max %ldns (%ld micros)\n",
484+
frcall1, max_call1, max_call1 / 1000);
485+
printf("Alternating vmcall VM2: %ldns, max %ldns (%ld micros)\n",
486+
frcall2, max_call2, max_call2 / 1000);
487+
}
488+
423489
void benchmark_alternate_tenant_resets(tinykvm::Machine& master_vm, const size_t RESETS)
424490
{
425491
const uint64_t vmcall_address = master_vm.address_of("bench");
@@ -475,8 +541,8 @@ void benchmark_alternate_tenant_resets(tinykvm::Machine& master_vm, const size_t
475541
frtime /= RESETS;
476542
frcall /= RESETS;
477543

478-
printf("Alternating reset: %ldns (%ld micros)\n", frtime, frtime / 1000);
479-
printf("Alternating vmcall: %ldns (%ld micros)\n", frcall, frcall / 1000);
544+
printf("Alternating reset: reset: %ldns (%ld micros)\n", frtime, frtime / 1000);
545+
printf("Alternating reset: vmcall: %ldns (%ld micros)\n", frcall, frcall / 1000);
480546
}
481547

482548
void benchmark_multiple_vms(tinykvm::Machine& master_vm, size_t NUM, size_t RESETS)

0 commit comments

Comments
 (0)