Check how long it takes to get dirty log according to the number of dirty pages, like: get dirty log: 49 us for 1 dirty pages get dirty log: 49 us for 2 dirty pages get dirty log: 45 us for 4 dirty pages get dirty log: 41 us for 8 dirty pages get dirty log: 40 us for 16 dirty pages get dirty log: 44 us for 32 dirty pages get dirty log: 39 us for 64 dirty pages get dirty log: 42 us for 128 dirty pages get dirty log: 45 us for 256 dirty pages get dirty log: 53 us for 512 dirty pages get dirty log: 72 us for 1024 dirty pages get dirty log: 99 us for 2048 dirty pages get dirty log: 132 us for 4096 dirty pages get dirty log: 224 us for 8192 dirty pages get dirty log: 383 us for 16384 dirty pages get dirty log: 725 us for 32768 dirty pages get dirty log: 1412 us for 65536 dirty pages get dirty log: 2746 us for 131072 dirty pages get dirty log: 5455 us for 262144 dirty pages Signed-off-by: Takuya Yoshikawa <takuya.yoshikawa@xxxxxxxxx> --- api/dirty-log-perf.cc | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ config-x86-common.mak | 3 + 2 files changed, 110 insertions(+), 0 deletions(-) create mode 100644 api/dirty-log-perf.cc diff --git a/api/dirty-log-perf.cc b/api/dirty-log-perf.cc new file mode 100644 index 0000000..83413ce --- /dev/null +++ b/api/dirty-log-perf.cc @@ -0,0 +1,107 @@ +#include "kvmxx.hh" +#include "memmap.hh" +#include "identity.hh" +#include <boost/thread/thread.hpp> +#include <stdlib.h> +#include <stdio.h> +#include <sys/time.h> + +namespace { + +const int page_size = 4096; +const int nr_pages = 256 * 1024; + +void delay_loop(unsigned n) +{ + for (unsigned i = 0; i < n; ++i) { + asm volatile("pause"); + } +} + +void write_mem(volatile bool& running, volatile int& nr_dirty_pages, + void* logged_slot_virt) +{ + while (nr_dirty_pages >= 0) { + char* var = static_cast<char*>(logged_slot_virt); + + while (!running) { + delay_loop(1000); + } + for (int i = 0; i < nr_dirty_pages; ++i) { + ++(*var); + var += page_size; + } + running = false; + } +} + +void check_dirty_log(mem_slot& slot, + volatile bool& running, + volatile int& nr_dirty_pages) +{ + slot.set_dirty_logging(true); + slot.update_dirty_log(); + + for (int i = 1; i <= nr_pages; i *= 2) { + struct timeval start_time, end_time; + long time_usec; + + nr_dirty_pages = i; + running = true; + // wait until the guest finishes writing + while (running) { + delay_loop(1000); + } + + gettimeofday(&start_time, NULL); + slot.update_dirty_log(); + gettimeofday(&end_time, NULL); + + time_usec = 1000 * 1000 * (end_time.tv_sec - start_time.tv_sec); + time_usec += end_time.tv_usec - start_time.tv_usec; + printf("get dirty log: %6ld us for %10d dirty pages\n", + time_usec, nr_dirty_pages); + } + + // stop the guest + nr_dirty_pages = -1; + running = true; + slot.set_dirty_logging(false); +} + +} + +using boost::ref; +using std::tr1::bind; + +int main(int ac, char **av) +{ + kvm::system sys; + kvm::vm vm(sys); + mem_map memmap(vm); + + void* logged_slot_virt; + int memory_size = nr_pages * page_size; + if (posix_memalign(&logged_slot_virt, page_size, memory_size)) { + printf("dirty-log-perf: Could not allocate guest memory.\n"); + exit(1); + } + + identity::hole hole(logged_slot_virt, memory_size); + identity::vm ident_vm(vm, memmap, hole); + kvm::vcpu vcpu(vm, 0); + mem_slot logged_slot(memmap, + reinterpret_cast<uint64_t>(logged_slot_virt), + memory_size, logged_slot_virt); + + bool running = false; + int nr_dirty_pages = 0; + boost::thread host_poll_thread(check_dirty_log, ref(logged_slot), + ref(running), ref(nr_dirty_pages)); + identity::vcpu guest_write_thread(vcpu, bind(write_mem, ref(running), + ref(nr_dirty_pages), + logged_slot_virt)); + vcpu.run(); + host_poll_thread.join(); + return 0; +} diff --git a/config-x86-common.mak b/config-x86-common.mak index 1cbc7c6..a3e8ffa 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -39,6 +39,7 @@ tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \ ifdef API tests-common += api/api-sample tests-common += api/dirty-log +tests-common += api/dirty-log-perf endif tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg @@ -102,3 +103,5 @@ api/libapi.a: api/kvmxx.o api/identity.o api/exception.o api/memmap.o api/api-sample: api/api-sample.o api/libapi.a api/dirty-log: api/dirty-log.o api/libapi.a + +api/dirty-log-perf: api/dirty-log-perf.o api/libapi.a -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html