[Libguestfs] [PATCH libnbd 2/3] examples: copy-libev: Do not initialize pread buffer

Nir Soffer nsoffer at redhat.com
Sun Mar 6 20:27:29 UTC 2022


This safety feature is not needed since we handle pread errors, and even
if we did not, we use initialized buffers. Testing shows 10% speedup
when copying a real image.

$ qemu-nbd --read-only --persistent --shared 8 --cache none --aio native \
    --socket /tmp/src.sock --format raw fedora-35-data.raw &

$ qemu-nbd --persistent --shared 8 --cache none --aio native --discard unmap \
    --socket /tmp/dst.sock --format raw dst.raw &

$ hyperfine -p "sleep 5" "./copy-libev-init $SRC $DST" "./copy-libev-no-init $SRC $DST"

Benchmark 1: ./copy-libev-init nbd+unix:///?socket=/tmp/src.sock nbd+unix:///?socket=/tmp/dst.sock
  Time (mean ± σ):      2.895 s ±  0.026 s    [User: 0.387 s, System: 1.645 s]
  Range (min … max):    2.853 s …  2.933 s    10 runs

Benchmark 2: ./copy-libev-no-init nbd+unix:///?socket=/tmp/src.sock nbd+unix:///?socket=/tmp/dst.sock
  Time (mean ± σ):      2.636 s ±  0.034 s    [User: 0.052 s, System: 1.628 s]
  Range (min … max):    2.557 s …  2.677 s    10 runs

Summary
  './copy-libev-no-init nbd+unix:///?socket=/tmp/src.sock nbd+unix:///?socket=/tmp/dst.sock' ran
    1.10 ± 0.02 times faster than './copy-libev-init nbd+unix:///?socket=/tmp/src.sock nbd+unix:///?socket=/tmp/dst.sock'

Signed-off-by: Nir Soffer <nsoffer at redhat.com>
---
 examples/copy-libev.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/examples/copy-libev.c b/examples/copy-libev.c
index ad50b64c..f36939a7 100644
--- a/examples/copy-libev.c
+++ b/examples/copy-libev.c
@@ -647,20 +647,26 @@ main (int argc, char *argv[])
 
     size = nbd_get_size (src.nbd);
 
     if (size > nbd_get_size (dst.nbd))
         FAIL ("Destinatio is not large enough\n");
 
     /* Check destination server capabilities. */
 
     dst.can_zero = nbd_can_zero (dst.nbd) > 0;
 
+    /* Disable pread buffer initialization. This is not needed since we
+     * handle pread errors, and even if we fail to handle errors, we use
+     * initialized buffers. */
+
+    nbd_set_pread_initialize (src.nbd, false);
+
     /* Start the copy "loop".  When request completes, it starts the
      * next request, until entire image was copied. */
 
     for (i = 0; i < MAX_REQUESTS; i++) {
         struct request *r = &requests[i];
         r->index = i;
 
         /*
          * Clear the buffer before starting the copy, so if we fail to
          * handle a read error we will not write uninitilized data to
-- 
2.35.1



More information about the Libguestfs mailing list