Rename BUFFER_SIZE to REQUEST_SIZE and get the value from an environment variable. Change the test script to test multiple values.
An example run: $ ./synch-parallel.sh Request size: 4096 thread 0: finished OK in 10.000019 seconds thread 4: finished OK in 10.000003 seconds thread 2: finished OK in 10.000015 seconds thread 1: finished OK in 10.000053 seconds thread 6: finished OK in 10.000075 seconds thread 7: finished OK in 10.000012 seconds thread 3: finished OK in 10.000024 seconds thread 5: finished OK in 10.000000 seconds TLS: disabled bytes sent: 2412867584 (230.109 MiB/s) bytes received: 2419851264 (230.775 MiB/s) I/O requests: 1179863 (117986 IOPS) Request size: 262144 thread 2: finished OK in 10.000030 seconds thread 5: finished OK in 10.000415 seconds thread 1: finished OK in 10.000500 seconds thread 3: finished OK in 10.000459 seconds thread 6: finished OK in 10.000275 seconds thread 4: finished OK in 10.000520 seconds thread 7: finished OK in 10.000529 seconds thread 0: finished OK in 10.000768 seconds TLS: disabled bytes sent: 12791840768 (1219.92 MiB/s) bytes received: 12748324864 (1215.78 MiB/s) I/O requests: 97428 (9742.8 IOPS) 4k is a good size to test IOPS, and 256k is a good size for getting maximum throughput. I kept the current default 16k as is. Signed-off-by: Nir Soffer <[email protected]> --- tests/synch-parallel.c | 51 +++++++++++++++++++++++++++++++++-------- tests/synch-parallel.sh | 12 ++++++---- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/tests/synch-parallel.c b/tests/synch-parallel.c index 423e1f0..d6ab1df 100644 --- a/tests/synch-parallel.c +++ b/tests/synch-parallel.c @@ -36,82 +36,115 @@ #include <sys/time.h> #include <pthread.h> #include <libnbd.h> #include "byte-swapping.h" /* We keep a shadow of the RAM disk so we can check integrity of the data. */ static char *ramdisk; /* This is also defined in synch-parallel.sh and checked here. */ #define EXPORTSIZE (8*1024*1024) /* How long (seconds) that the test will run for. */ #define RUN_TIME 10 /* Number of threads. */ #define NR_THREADS 8 -#define MiB (1024*1024) +#define KiB 1024 +#define MiB (1024*KiB) #define MICROSECONDS 1000000 /* Unix socket. */ static const char *unixsocket; +static long request_size; + struct thread_status { size_t i; /* Thread index, 0 .. NR_THREADS-1 */ uint64_t offset, length; /* Area assigned to this thread. */ int status; /* Return status. */ unsigned requests; /* Total number of requests made. */ uint64_t bytes_sent, bytes_received; /* Bytes sent and received by thread. */ }; static void *start_thread (void *arg); static inline int64_t microtime (void) { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * MICROSECONDS + tv.tv_usec; } +static long +getenv_long(const char *name, long defval) +{ + const char *value; + char *end; + long res; + + value = getenv (name); + if (value == NULL) + return defval; + + res = strtol(value, &end, 10); + if (*end != '\0' || end == value) { + fprintf (stderr, "Invalid value for %s: '%s'\n", name, value); + exit (EXIT_FAILURE); + } + + return res; +} + int main (int argc, char *argv[]) { pthread_t threads[NR_THREADS]; struct thread_status status[NR_THREADS]; size_t i; int err; unsigned requests, errors; uint64_t bytes_sent, bytes_received; if (argc != 2) { fprintf (stderr, "%s socket\n", argv[0]); exit (EXIT_FAILURE); } unixsocket = argv[1]; + request_size = getenv_long ("REQUEST_SIZE", 16*KiB); + if (request_size < 4*KiB || + request_size > 512*KiB || + (EXPORTSIZE / NR_THREADS) % request_size != 0) { + fprintf (stderr, + "Invalid REQUEST_SIZE environment variable: %ld\n", + request_size); + exit (EXIT_FAILURE); + } + srand ((microtime () / MICROSECONDS) + getpid ()); /* Initialize the RAM disk with the initial data from * nbdkit-pattern-filter. */ ramdisk = malloc (EXPORTSIZE); if (ramdisk == NULL) { perror ("calloc"); exit (EXIT_FAILURE); } for (i = 0; i < EXPORTSIZE; i += 8) { uint64_t d = htobe64 (i); memcpy (&ramdisk[i], &d, sizeof d); } /* Start the worker threads. */ for (i = 0; i < NR_THREADS; ++i) { status[i].i = i; status[i].offset = i * EXPORTSIZE / NR_THREADS; status[i].length = EXPORTSIZE / NR_THREADS; @@ -152,53 +185,51 @@ main (int argc, char *argv[]) /* Print some stats. */ printf ("TLS: %s\n", #ifdef TLS "enabled" #else "disabled" #endif ); printf ("bytes sent: %" PRIu64 " (%g MiB/s)\n", bytes_sent, (double) bytes_sent / RUN_TIME / MiB); printf ("bytes received: %" PRIu64 " (%g MiB/s)\n", bytes_received, (double) bytes_received / RUN_TIME / MiB); printf ("I/O requests: %u (%g IOPS)\n", requests, (double) requests / RUN_TIME); exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } -#define BUFFER_SIZE 16384 - static void * start_thread (void *arg) { struct thread_status *status = arg; struct nbd_handle *nbd; char *buf; int cmd; uint64_t offset; int64_t start_usec, stop_usec, now_usec; - buf = calloc (BUFFER_SIZE, 1); + buf = calloc (request_size, 1); if (buf == NULL) { perror ("calloc"); exit (EXIT_FAILURE); } nbd = nbd_create (); if (nbd == NULL) { fprintf (stderr, "%s\n", nbd_get_error ()); exit (EXIT_FAILURE); } #ifdef TLS /* Require TLS on the handle and fail if not available or if the * handshake fails. */ if (nbd_set_tls (nbd, LIBNBD_TLS_REQUIRE) == -1) { fprintf (stderr, "%s\n", nbd_get_error ()); exit (EXIT_FAILURE); } @@ -217,58 +248,58 @@ start_thread (void *arg) if (nbd_connect_unix (nbd, unixsocket) == -1) { fprintf (stderr, "%s\n", nbd_get_error ()); exit (EXIT_FAILURE); } assert (nbd_get_size (nbd) == EXPORTSIZE); assert (nbd_can_multi_conn (nbd) > 0); assert (nbd_is_read_only (nbd) == 0); start_usec = microtime (); stop_usec = start_usec + RUN_TIME * MICROSECONDS; /* Issue commands. */ while (1) { /* Run until the timer expires. */ now_usec = microtime (); if (now_usec >= stop_usec) break; /* Issue a synchronous read or write command. */ - offset = status->offset + (rand () % (status->length - BUFFER_SIZE)); + offset = status->offset + (rand () % (status->length - request_size)); cmd = rand () & 1; if (cmd == 0) { /* Write block from ramdisk to nbd server. */ - if (nbd_pwrite (nbd, &ramdisk[offset], BUFFER_SIZE, offset, 0) == -1) { + if (nbd_pwrite (nbd, &ramdisk[offset], request_size, offset, 0) == -1) { fprintf (stderr, "%s\n", nbd_get_error ()); goto error; } - status->bytes_sent += BUFFER_SIZE; + status->bytes_sent += request_size; } else { /* Read block from nbd server to buf. */ - if (nbd_pread (nbd, buf, BUFFER_SIZE, offset, 0) == -1) { + if (nbd_pread (nbd, buf, request_size, offset, 0) == -1) { fprintf (stderr, "%s\n", nbd_get_error ()); goto error; } - status->bytes_received += BUFFER_SIZE; - if (memcmp (&ramdisk[offset], buf, BUFFER_SIZE) != 0) { + status->bytes_received += request_size; + if (memcmp (&ramdisk[offset], buf, request_size) != 0) { fprintf (stderr, "thread %zu: DATA INTEGRITY ERROR!\n", status->i); goto error; } } status->requests++; } printf ("thread %zu: finished OK in %.6f seconds\n", status->i, (double) (now_usec - start_usec) / MICROSECONDS); if (nbd_shutdown (nbd, 0) == -1) { fprintf (stderr, "%s\n", nbd_get_error ()); goto error; } nbd_close (nbd); free (buf); status->status = 0; diff --git a/tests/synch-parallel.sh b/tests/synch-parallel.sh index 84c00d8..0ca9060 100755 --- a/tests/synch-parallel.sh +++ b/tests/synch-parallel.sh @@ -1,24 +1,28 @@ #!/usr/bin/env bash # nbd client library in userspace # Copyright (C) 2019 Red Hat Inc. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # Test synchronous parallel high level API requests. -nbdkit -U - \ - --filter=cow \ - pattern size=8M \ - --run '$VG ./synch-parallel $unixsocket' +for request_size in 4096 262144; do + echo "Request size: $request_size" + REQUEST_SIZE=$request_size nbdkit -U - \ + --filter=cow \ + pattern size=8M \ + --run '$VG ./synch-parallel $unixsocket' + echo +done -- 2.31.1 _______________________________________________ Libguestfs mailing list [email protected] https://listman.redhat.com/mailman/listinfo/libguestfs
