Nir Soffer
2022-Mar-06 20:27 UTC
[Libguestfs] [PATCH libnbd 1/3] golang: examples: Do not initialize pread buffer
The aio_copy example checks errors properly, so it will not leak uninitialized memory to the destination image. Testing shows 5% 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 & $ hyperfine -p "sleep 5" "./aio_copy-init $SRC >/dev/null" "./aio_copy-no-init $SRC >/dev/null" Benchmark 1: ./aio_copy-init nbd+unix:///?socket=/tmp/src.sock >/dev/null Time (mean ? ?): 1.452 s ? 0.027 s [User: 0.330 s, System: 0.489 s] Range (min ? max): 1.426 s ? 1.506 s 10 runs Benchmark 2: ./aio_copy-no-init nbd+unix:///?socket=/tmp/src.sock >/dev/null Time (mean ? ?): 1.378 s ? 0.009 s [User: 0.202 s, System: 0.484 s] Range (min ? max): 1.369 s ? 1.399 s 10 runs Summary './aio_copy-no-init nbd+unix:///?socket=/tmp/src.sock >/dev/null' ran 1.05 ? 0.02 times faster than './aio_copy-init nbd+unix:///?socket=/tmp/src.sock >/dev/null' Signed-off-by: Nir Soffer <nsoffer at redhat.com> --- golang/examples/aio_copy/aio_copy.go | 5 +++++ golang/examples/simple_copy/simple_copy.go | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/golang/examples/aio_copy/aio_copy.go b/golang/examples/aio_copy/aio_copy.go index bb20b478..89eac4df 100644 --- a/golang/examples/aio_copy/aio_copy.go +++ b/golang/examples/aio_copy/aio_copy.go @@ -84,20 +84,25 @@ func main() { err = h.ConnectUri(flag.Arg(0)) if err != nil { panic(err) } size, err := h.GetSize() if err != nil { panic(err) } + err = h.SetPreadInitialize(false) + if err != nil { + panic(err) + } + var offset uint64 for offset < size || queue.Len() > 0 { for offset < size && inflightRequests() < *requests { length := *requestSize if size-offset < uint64(length) { length = uint(size - offset) } startRead(offset, length) diff --git a/golang/examples/simple_copy/simple_copy.go b/golang/examples/simple_copy/simple_copy.go index e8fa1f76..2a2ed0ff 100644 --- a/golang/examples/simple_copy/simple_copy.go +++ b/golang/examples/simple_copy/simple_copy.go @@ -63,20 +63,25 @@ func main() { err = h.ConnectUri(flag.Arg(0)) if err != nil { panic(err) } size, err := h.GetSize() if err != nil { panic(err) } + err = h.SetPreadInitialize(false) + if err != nil { + panic(err) + } + buf := make([]byte, *requestSize) var offset uint64 for offset < size { if size-offset < uint64(len(buf)) { buf = buf[:offset-size] } err = h.Pread(buf, offset, nil) if err != nil { -- 2.35.1
Richard W.M. Jones
2022-Mar-06 20:35 UTC
[Libguestfs] [PATCH libnbd 1/3] golang: examples: Do not initialize pread buffer
On Sun, Mar 06, 2022 at 10:27:28PM +0200, Nir Soffer wrote:> The aio_copy example checks errors properly, so it will not leak > uninitialized memory to the destination image. Testing shows 5% 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 & > > $ hyperfine -p "sleep 5" "./aio_copy-init $SRC >/dev/null" "./aio_copy-no-init $SRC >/dev/null" > > Benchmark 1: ./aio_copy-init nbd+unix:///?socket=/tmp/src.sock >/dev/null > Time (mean ? ?): 1.452 s ? 0.027 s [User: 0.330 s, System: 0.489 s] > Range (min ? max): 1.426 s ? 1.506 s 10 runs > > Benchmark 2: ./aio_copy-no-init nbd+unix:///?socket=/tmp/src.sock >/dev/null > Time (mean ? ?): 1.378 s ? 0.009 s [User: 0.202 s, System: 0.484 s] > Range (min ? max): 1.369 s ? 1.399 s 10 runs > > Summary > './aio_copy-no-init nbd+unix:///?socket=/tmp/src.sock >/dev/null' ran > 1.05 ? 0.02 times faster than './aio_copy-init nbd+unix:///?socket=/tmp/src.sock >/dev/null' > > Signed-off-by: Nir Soffer <nsoffer at redhat.com> > --- > golang/examples/aio_copy/aio_copy.go | 5 +++++ > golang/examples/simple_copy/simple_copy.go | 5 +++++ > 2 files changed, 10 insertions(+) > > diff --git a/golang/examples/aio_copy/aio_copy.go b/golang/examples/aio_copy/aio_copy.go > index bb20b478..89eac4df 100644 > --- a/golang/examples/aio_copy/aio_copy.go > +++ b/golang/examples/aio_copy/aio_copy.go > @@ -84,20 +84,25 @@ func main() { > err = h.ConnectUri(flag.Arg(0)) > if err != nil { > panic(err) > } > > size, err := h.GetSize() > if err != nil { > panic(err) > } > > + err = h.SetPreadInitialize(false) > + if err != nil { > + panic(err) > + } > +In patch #2 you added a comment above the call. Because this is an example and so people may just copy the code blindly without understanding it, I think adding a comment here and below is worth doing too.> diff --git a/golang/examples/simple_copy/simple_copy.go b/golang/examples/simple_copy/simple_copy.go > index e8fa1f76..2a2ed0ff 100644 > --- a/golang/examples/simple_copy/simple_copy.go > +++ b/golang/examples/simple_copy/simple_copy.go > @@ -63,20 +63,25 @@ func main() { > err = h.ConnectUri(flag.Arg(0)) > if err != nil { > panic(err) > } > > size, err := h.GetSize() > if err != nil { > panic(err) > } > > + err = h.SetPreadInitialize(false) > + if err != nil { > + panic(err) > + } > +And above this one. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v