Blame SOURCES/0019-common-utils-test-vector.c-Add-vector-benchmarks.patch

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