diff --git a/examples/guestfs-performance.pod b/examples/guestfs-performance.pod index d0395c922..f60d8bf63 100644 --- a/examples/guestfs-performance.pod +++ b/examples/guestfs-performance.pod @@ -267,6 +267,107 @@ Linux but expensive on Windows. =back +=head1 PARALLEL APPLIANCES + +Libguestfs appliances are mostly I/O bound and you can launch multiple +appliances in parallel. Provided there is enough free memory, there +should be little difference in launching 1 appliance vs N appliances +in parallel. + +On a 2-core (4-thread) laptop with 16 GB of RAM, using the (not +especially realistic) test Perl script below, the following plot shows +excellent scalability when running between 1 and 20 appliances in +parallel: + + 12 ++---+----+----+----+-----+----+----+----+----+---++ + + + + + + + + + + + * + | | + | * | + 11 ++ ++ + | | + | | + | * * | + 10 ++ ++ + | * | + | | + s | | + 9 ++ ++ + e | | + | * | + c | | + 8 ++ * ++ + o | * | + | | + n 7 ++ ++ + | * | + d | * | + | | + s 6 ++ ++ + | * * | + | * | + | | + 5 ++ ++ + | | + | * | + | * * | + 4 ++ ++ + | | + | | + + * * * + + + + + + + + + 3 ++-*-+----+----+----+-----+----+----+----+----+---++ + 0 2 4 6 8 10 12 14 16 18 20 + number of parallel appliances + +It is possible to run many more than 20 appliances in parallel, but if +you are using the libvirt backend then you should be aware that out of +the box libvirt limits the number of client connections to 20. + +The simple Perl script below was used to collect the data for the plot +above, but there is much more information on this subject, including +more advanced test scripts and graphs, available in the following blog +postings: + +L +L +L +L + + #!/usr/bin/perl -w + + use strict; + use threads; + use Sys::Guestfs; + use Time::HiRes qw(time); + + sub test { + my $g = Sys::Guestfs->new; + $g->add_drive_ro ("/dev/null"); + $g->launch (); + + # You could add some work for libguestfs to do here. + + $g->close (); + } + + # Get everything into cache. + test (); test (); test (); + + for my $nr_threads (1..20) { + my $start_t = time (); + my @threads; + foreach (1..$nr_threads) { + push @threads, threads->create (\&test) + } + foreach (@threads) { + $_->join (); + if (my $err = $_->error ()) { + die "launch failed with $nr_threads threads: $err" + } + } + my $end_t = time (); + printf ("%d %.2f\n", $nr_threads, $end_t - $start_t); + } + =head1 TROUBLESHOOTING POOR PERFORMANCE =head2 ENSURE HARDWARE VIRTUALIZATION IS AVAILABLE