|
|
e7ca0c |
From 4cc4e2cfc6202d522b3c4282bbaedf3d47de16bb Mon Sep 17 00:00:00 2001
|
|
|
7084e2 |
From: Nir Soffer <nsoffer@redhat.com>
|
|
|
7084e2 |
Date: Fri, 5 Nov 2021 20:36:42 +0200
|
|
|
7084e2 |
Subject: [PATCH] common/utils/test-vector.c: Add vector benchmarks
|
|
|
7084e2 |
|
|
|
7084e2 |
The generic vector reallocs on every append. Add benchmarks to measure
|
|
|
7084e2 |
the cost with uint32 vector (used for copying extents) and the effect of
|
|
|
7084e2 |
reserving space upfront.
|
|
|
7084e2 |
|
|
|
7084e2 |
The tests show that realloc is pretty efficient, but calling reserve
|
|
|
7084e2 |
before the appends speeds the appends up significantly.
|
|
|
7084e2 |
|
|
|
7084e2 |
NBDKIT_BENCH=1 ./test-vector
|
|
|
7084e2 |
bench_reserve: 1000000 appends in 0.004503 s
|
|
|
7084e2 |
bench_append: 1000000 appends in 0.014986 s
|
|
|
7084e2 |
|
|
|
7084e2 |
The new benchmarks do not run by default to avoid trouble in CI on
|
|
|
7084e2 |
overloaded machines or under qemu emulation.
|
|
|
7084e2 |
|
|
|
7084e2 |
A new target added to run all benchmaks:
|
|
|
7084e2 |
|
|
|
7084e2 |
make bench
|
|
|
7084e2 |
|
|
|
7084e2 |
Ported from libnbd:
|
|
|
7084e2 |
- commit dc9ae0174ab1384081a57a8d54b10f8147ea6430
|
|
|
7084e2 |
- commit f6c06a3b4d87fe976a96ea04f8da1f22b2531dbd
|
|
|
7084e2 |
|
|
|
7084e2 |
(cherry picked from commit a227af7921c9a51c4f1ab699a3b9f06a9a645126)
|
|
|
7084e2 |
---
|
|
|
7084e2 |
Makefile.am | 5 +++
|
|
|
7084e2 |
README | 7 ++++
|
|
|
7084e2 |
common/utils/Makefile.am | 5 ++-
|
|
|
7084e2 |
common/utils/bench.h | 72 ++++++++++++++++++++++++++++++++++++++
|
|
|
7084e2 |
common/utils/test-vector.c | 55 +++++++++++++++++++++++++++--
|
|
|
7084e2 |
5 files changed, 141 insertions(+), 3 deletions(-)
|
|
|
7084e2 |
create mode 100644 common/utils/bench.h
|
|
|
7084e2 |
|
|
|
7084e2 |
diff --git a/Makefile.am b/Makefile.am
|
|
|
7084e2 |
index b21d69ed..49f5d91c 100644
|
|
|
7084e2 |
--- a/Makefile.am
|
|
|
7084e2 |
+++ b/Makefile.am
|
|
|
7084e2 |
@@ -102,6 +102,11 @@ check-root:
|
|
|
7084e2 |
check-vddk:
|
|
|
7084e2 |
$(MAKE) -C tests check-vddk
|
|
|
7084e2 |
|
|
|
7084e2 |
+bench: all
|
|
|
7084e2 |
+ @for d in common/utils; do \
|
|
|
7084e2 |
+ $(MAKE) -C $$d bench || exit 1; \
|
|
|
7084e2 |
+ done
|
|
|
7084e2 |
+
|
|
|
7084e2 |
#----------------------------------------------------------------------
|
|
|
7084e2 |
# Maintainers only!
|
|
|
7084e2 |
|
|
|
7084e2 |
diff --git a/README b/README
|
|
|
7084e2 |
index a04325be..b001620c 100644
|
|
|
7084e2 |
--- a/README
|
|
|
7084e2 |
+++ b/README
|
|
|
7084e2 |
@@ -274,6 +274,13 @@ nbdkit-vddk-plugin against the library like this:
|
|
|
7084e2 |
|
|
|
7084e2 |
make check-vddk vddkdir=vmware-vix-disklib-distrib
|
|
|
7084e2 |
|
|
|
7084e2 |
+Running the benchmarks
|
|
|
7084e2 |
+----------------------
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+To run benchmarks:
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ make bench
|
|
|
7084e2 |
+
|
|
|
7084e2 |
DOWNLOAD TARBALLS
|
|
|
7084e2 |
=================
|
|
|
7084e2 |
|
|
|
7084e2 |
diff --git a/common/utils/Makefile.am b/common/utils/Makefile.am
|
|
|
7084e2 |
index 14e9dfc4..55415535 100644
|
|
|
7084e2 |
--- a/common/utils/Makefile.am
|
|
|
7084e2 |
+++ b/common/utils/Makefile.am
|
|
|
7084e2 |
@@ -100,6 +100,9 @@ test_quotes_SOURCES = test-quotes.c quote.c utils.h
|
|
|
7084e2 |
test_quotes_CPPFLAGS = -I$(srcdir)
|
|
|
7084e2 |
test_quotes_CFLAGS = $(WARNINGS_CFLAGS)
|
|
|
7084e2 |
|
|
|
7084e2 |
-test_vector_SOURCES = test-vector.c vector.c vector.h
|
|
|
7084e2 |
+test_vector_SOURCES = test-vector.c vector.c vector.h bench.h
|
|
|
7084e2 |
test_vector_CPPFLAGS = -I$(srcdir)
|
|
|
7084e2 |
test_vector_CFLAGS = $(WARNINGS_CFLAGS)
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+bench: test-vector
|
|
|
7084e2 |
+ NBDKIT_BENCH=1 ./test-vector
|
|
|
7084e2 |
diff --git a/common/utils/bench.h b/common/utils/bench.h
|
|
|
7084e2 |
new file mode 100644
|
|
|
7084e2 |
index 00000000..496a3614
|
|
|
7084e2 |
--- /dev/null
|
|
|
7084e2 |
+++ b/common/utils/bench.h
|
|
|
7084e2 |
@@ -0,0 +1,72 @@
|
|
|
7084e2 |
+/* libnbd
|
|
|
7084e2 |
+ * Copyright (C) 2021 Red Hat Inc.
|
|
|
7084e2 |
+ *
|
|
|
7084e2 |
+ * Redistribution and use in source and binary forms, with or without
|
|
|
7084e2 |
+ * modification, are permitted provided that the following conditions are
|
|
|
7084e2 |
+ * met:
|
|
|
7084e2 |
+ *
|
|
|
7084e2 |
+ * * Redistributions of source code must retain the above copyright
|
|
|
7084e2 |
+ * notice, this list of conditions and the following disclaimer.
|
|
|
7084e2 |
+ *
|
|
|
7084e2 |
+ * * Redistributions in binary form must reproduce the above copyright
|
|
|
7084e2 |
+ * notice, this list of conditions and the following disclaimer in the
|
|
|
7084e2 |
+ * documentation and/or other materials provided with the distribution.
|
|
|
7084e2 |
+ *
|
|
|
7084e2 |
+ * * Neither the name of Red Hat nor the names of its contributors may be
|
|
|
7084e2 |
+ * used to endorse or promote products derived from this software without
|
|
|
7084e2 |
+ * specific prior written permission.
|
|
|
7084e2 |
+ *
|
|
|
7084e2 |
+ * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
|
|
|
7084e2 |
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
|
7084e2 |
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
|
7084e2 |
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
|
|
|
7084e2 |
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
7084e2 |
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
7084e2 |
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
|
7084e2 |
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
|
7084e2 |
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
|
7084e2 |
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
|
|
7084e2 |
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
7084e2 |
+ * SUCH DAMAGE.
|
|
|
7084e2 |
+ */
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+#ifndef LIBNBD_BENCH_H
|
|
|
7084e2 |
+#define LIBNBD_BENCH_H
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+#include <sys/time.h>
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+#define MICROSECONDS 1000000
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+struct bench {
|
|
|
7084e2 |
+ struct timeval start, stop;
|
|
|
7084e2 |
+};
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+static inline void
|
|
|
7084e2 |
+bench_start(struct bench *b)
|
|
|
7084e2 |
+{
|
|
|
7084e2 |
+ gettimeofday (&b->start, NULL);
|
|
|
7084e2 |
+}
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+static inline void
|
|
|
7084e2 |
+bench_stop(struct bench *b)
|
|
|
7084e2 |
+{
|
|
|
7084e2 |
+ gettimeofday (&b->stop, NULL);
|
|
|
7084e2 |
+}
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+static inline double
|
|
|
7084e2 |
+bench_sec(struct bench *b)
|
|
|
7084e2 |
+{
|
|
|
7084e2 |
+ struct timeval dt;
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ dt.tv_sec = b->stop.tv_sec - b->start.tv_sec;
|
|
|
7084e2 |
+ dt.tv_usec = b->stop.tv_usec - b->start.tv_usec;
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ if (dt.tv_usec < 0) {
|
|
|
7084e2 |
+ dt.tv_sec -= 1;
|
|
|
7084e2 |
+ dt.tv_usec += MICROSECONDS;
|
|
|
7084e2 |
+ }
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ return ((double)dt.tv_sec * MICROSECONDS + dt.tv_usec) / MICROSECONDS;
|
|
|
7084e2 |
+}
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+#endif /* LIBNBD_BENCH_H */
|
|
|
7084e2 |
diff --git a/common/utils/test-vector.c b/common/utils/test-vector.c
|
|
|
7084e2 |
index 94b2aeb7..28af59b8 100644
|
|
|
7084e2 |
--- a/common/utils/test-vector.c
|
|
|
7084e2 |
+++ b/common/utils/test-vector.c
|
|
|
7084e2 |
@@ -38,9 +38,13 @@
|
|
|
7084e2 |
#undef NDEBUG /* Keep test strong even for nbdkit built without assertions */
|
|
|
7084e2 |
#include <assert.h>
|
|
|
7084e2 |
|
|
|
7084e2 |
+#include "bench.h"
|
|
|
7084e2 |
#include "vector.h"
|
|
|
7084e2 |
|
|
|
7084e2 |
+#define APPENDS 1000000
|
|
|
7084e2 |
+
|
|
|
7084e2 |
DEFINE_VECTOR_TYPE(int64_vector, int64_t);
|
|
|
7084e2 |
+DEFINE_VECTOR_TYPE(uint32_vector, uint32_t);
|
|
|
7084e2 |
DEFINE_VECTOR_TYPE(string_vector, char *);
|
|
|
7084e2 |
|
|
|
7084e2 |
static int
|
|
|
7084e2 |
@@ -113,10 +117,57 @@ test_string_vector (void)
|
|
|
7084e2 |
free (v.ptr);
|
|
|
7084e2 |
}
|
|
|
7084e2 |
|
|
|
7084e2 |
+static void
|
|
|
7084e2 |
+bench_reserve (void)
|
|
|
7084e2 |
+{
|
|
|
7084e2 |
+ uint32_vector v = empty_vector;
|
|
|
7084e2 |
+ struct bench b;
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ bench_start(&b);
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ uint32_vector_reserve(&v, APPENDS);
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ for (uint32_t i = 0; i < APPENDS; i++) {
|
|
|
7084e2 |
+ uint32_vector_append (&v, i);
|
|
|
7084e2 |
+ }
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ bench_stop(&b);
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ assert (v.ptr[APPENDS - 1] == APPENDS - 1);
|
|
|
7084e2 |
+ free (v.ptr);
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ printf ("bench_reserve: %d appends in %.6f s\n", APPENDS, bench_sec (&b);;
|
|
|
7084e2 |
+}
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+static void
|
|
|
7084e2 |
+bench_append (void)
|
|
|
7084e2 |
+{
|
|
|
7084e2 |
+ uint32_vector v = empty_vector;
|
|
|
7084e2 |
+ struct bench b;
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ bench_start(&b);
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ for (uint32_t i = 0; i < APPENDS; i++) {
|
|
|
7084e2 |
+ uint32_vector_append (&v, i);
|
|
|
7084e2 |
+ }
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ bench_stop(&b);
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ assert (v.ptr[APPENDS - 1] == APPENDS - 1);
|
|
|
7084e2 |
+ free (v.ptr);
|
|
|
7084e2 |
+
|
|
|
7084e2 |
+ printf ("bench_append: %d appends in %.6f s\n", APPENDS, bench_sec (&b);;
|
|
|
7084e2 |
+}
|
|
|
7084e2 |
+
|
|
|
7084e2 |
int
|
|
|
7084e2 |
main (int argc, char *argv[])
|
|
|
7084e2 |
{
|
|
|
7084e2 |
- test_int64_vector ();
|
|
|
7084e2 |
- test_string_vector ();
|
|
|
7084e2 |
+ if (getenv("NBDKIT_BENCH")) {
|
|
|
7084e2 |
+ bench_reserve ();
|
|
|
7084e2 |
+ bench_append ();
|
|
|
7084e2 |
+ } else {
|
|
|
7084e2 |
+ test_int64_vector ();
|
|
|
7084e2 |
+ test_string_vector ();
|
|
|
7084e2 |
+ }
|
|
|
7084e2 |
return 0;
|
|
|
7084e2 |
}
|
|
|
7084e2 |
--
|
|
|
7084e2 |
2.31.1
|
|
|
7084e2 |
|