Add large block support to zpios(1) benchmark

As part of the large block support effort, it makes sense to add
support for large blocks to **zpios(1)**. The specifying of a zfs
block size for zpios is optional and will default to 128K if the
block size is not specified.

  `zpios ... -S size | --blocksize size ...`

This will use *size* ZFS blocks for each test, specified as a comma
delimited list with an optional unit suffix. The supported range is
powers of two from 128K through 16M. A range of block sizes can be
tested as follows: `-S 128K,256K,512K,1M`

Example run below
(non realistic results from a VM and output abbreviated for space)

```
 --regioncount=750 --regionsize=8M --chunksize=1M --offset=4K
 --threaddelay=0 --cleanup --human-readable --verbose --cleanup
 --blocksize=128K,256K,512K,1M

 th-cnt  rg-cnt  rg-sz  ch-sz  blksz  wr-data wr-bw   rd-data rd-bw
---------------------------------------------------------------------
 4       750     8m     1m     128k   5g      90.06m  5g      93.37m
 4       750     8m     1m     256k   5g      79.71m  5g      99.81m
 4       750     8m     1m     512k   5g      42.20m  5g      93.14m
 4       750     8m     1m     1m     5g      35.51m  5g      89.36m
 8       750     8m     1m     128k   5g      85.49m  5g      90.81m
 8       750     8m     1m     256k   5g      61.42m  5g      99.24m
 8       750     8m     1m     512k   5g      49.09m  5g     108.78m
 16      750     8m     1m     128k   5g      86.28m  5g      88.73m
 16      750     8m     1m     256k   5g      64.34m  5g      93.47m
 16      750     8m     1m     512k   5g      68.84m  5g     124.47m
 16      750     8m     1m     1m     5g      53.97m  5g      97.20m
---------------------------------------------------------------------
```

Signed-off-by: Don Brady <don.brady@intel.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #3795
Closes #2071
This commit is contained in:
Don Brady
2015-09-17 17:55:22 -06:00
committed by Brian Behlendorf
parent e7a05183c4
commit 56b3986316
7 changed files with 127 additions and 17 deletions
+8 -3
View File
@@ -29,6 +29,8 @@
*
* You should have received a copy of the GNU General Public License along
* with ZPIOS. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (c) 2015, Intel Corporation.
*/
#ifndef _ZPIOS_H
@@ -39,10 +41,10 @@
#define VERSION_SIZE 64
/* Regular expressions */
#define REGEX_NUMBERS "^[0-9]*[0-9]$"
#define REGEX_NUMBERS "^[0-9]+$"
#define REGEX_NUMBERS_COMMA "^([0-9]+,)*[0-9]+$"
#define REGEX_SIZE "^[0-9][0-9]*[kmgt]$"
#define REGEX_SIZE_COMMA "^([0-9][0-9]*[kmgt]+,)*[0-9][0-9]*[kmgt]$"
#define REGEX_SIZE "^[0-9]+[kKmMgGtT]?$"
#define REGEX_SIZE_COMMA "^([0-9]+[kKmMgGtT]?,)*[0-9]+[kKmMgGtT]?$"
/* Flags for low, high, incr */
#define FLAG_SET 0x01
@@ -82,10 +84,12 @@ typedef struct cmd_args {
range_repeat_t O; /* Offset count */
range_repeat_t C; /* Chunksize */
range_repeat_t S; /* Regionsize */
range_repeat_t B; /* Blocksize */
const char *pool; /* Pool */
const char *name; /* Name */
uint32_t flags; /* Flags */
uint32_t block_size; /* ZFS block size */
uint32_t io_type; /* DMUIO only */
uint32_t verbose; /* Verbose */
uint32_t human_readable; /* Human readable output */
@@ -105,6 +109,7 @@ typedef struct cmd_args {
uint64_t current_C;
uint64_t current_S;
uint64_t current_O;
uint64_t current_B;
uint32_t rc;
} cmd_args_t;
+50 -5
View File
@@ -29,6 +29,8 @@
*
* You should have received a copy of the GNU General Public License along
* with ZPIOS. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (c) 2015, Intel Corporation.
*/
#include <stdlib.h>
@@ -44,7 +46,7 @@
static const char short_opt[] =
"t:l:h:e:n:i:j:k:o:m:q:r:c:a:b:g:s:A:B:C:"
"L:p:M:xP:R:G:I:N:T:VzOfHv?";
"S:L:p:M:xP:R:G:I:N:T:VzOfHv?";
static const struct option long_opt[] = {
{"threadcount", required_argument, 0, 't' },
{"threadcount_low", required_argument, 0, 'l' },
@@ -66,6 +68,7 @@ static const struct option long_opt[] = {
{"regionsize_low", required_argument, 0, 'A' },
{"regionsize_high", required_argument, 0, 'B' },
{"regionsize_incr", required_argument, 0, 'C' },
{"blocksize", required_argument, 0, 'S' },
{"load", required_argument, 0, 'L' },
{"pool", required_argument, 0, 'p' },
{"name", required_argument, 0, 'M' },
@@ -116,6 +119,7 @@ usage(void)
" --regionsize_low -A =value\n"
" --regionsize_high -B =value\n"
" --regionsize_incr -C =value\n"
" --blocksize -S =values\n"
" --load -L =dmuio|ssf|fpp\n"
" --pool -p =pool name\n"
" --name -M =test name\n"
@@ -143,6 +147,11 @@ static void args_fini(cmd_args_t *args)
free(args);
}
/* block size is 128K to 16M, power of 2 */
#define MIN_BLKSIZE (128ULL << 10)
#define MAX_BLKSIZE (16ULL << 20)
#define POW_OF_TWO(x) (((x) & ((x) - 1)) == 0)
static cmd_args_t *
args_init(int argc, char **argv)
{
@@ -152,7 +161,8 @@ args_init(int argc, char **argv)
uint32_t fl_of = 0;
uint32_t fl_rs = 0;
uint32_t fl_cs = 0;
int c, rc;
uint32_t fl_bs = 0;
int c, rc, i;
if (argc == 1) {
usage();
@@ -166,6 +176,11 @@ args_init(int argc, char **argv)
memset(args, 0, sizeof (*args));
/* provide a default block size of 128K */
args->B.next_val = 0;
args->B.val[0] = MIN_BLKSIZE;
args->B.val_count = 1;
while ((c = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) {
rc = 0;
@@ -250,6 +265,10 @@ args_init(int argc, char **argv)
rc = set_lhi(REGEX_NUMBERS, &args->S, optarg,
FLAG_INCR, &fl_rs, "regionsize_incr");
break;
case 'S': /* --blocksize */
rc = set_count(REGEX_SIZE, REGEX_SIZE_COMMA,
&args->B, optarg, &fl_bs, "blocksize");
break;
case 'L': /* --load */
rc = set_load_params(args, optarg);
break;
@@ -339,6 +358,17 @@ args_init(int argc, char **argv)
return (NULL);
}
/* validate block size(s) */
for (i = 0; i < args->B.val_count; i++) {
int bs = args->B.val[i];
if (bs < MIN_BLKSIZE || bs > MAX_BLKSIZE || !POW_OF_TWO(bs)) {
fprintf(stderr, "Error: invalid block size %d\n", bs);
args_fini(args);
return (NULL);
}
}
return (args);
}
@@ -480,7 +510,7 @@ get_next(uint64_t *val, range_repeat_t *range)
static int
run_one(cmd_args_t *args, uint32_t id, uint32_t T, uint32_t N,
uint64_t C, uint64_t S, uint64_t O)
uint64_t C, uint64_t S, uint64_t O, uint64_t B)
{
zpios_cmd_t *cmd;
int rc, rc2, cmd_size;
@@ -506,6 +536,7 @@ run_one(cmd_args_t *args, uint32_t id, uint32_t T, uint32_t N,
cmd->cmd_region_count = N;
cmd->cmd_region_size = S;
cmd->cmd_offset = O;
cmd->cmd_block_size = B;
cmd->cmd_region_noise = args->regionnoise;
cmd->cmd_chunk_noise = args->chunknoise;
cmd->cmd_thread_delay = args->thread_delay;
@@ -541,7 +572,7 @@ run_offsets(cmd_args_t *args)
while (rc == 0 && get_next(&args->current_O, &args->O)) {
rc = run_one(args, args->current_id,
args->current_T, args->current_N, args->current_C,
args->current_S, args->current_O);
args->current_S, args->current_O, args->current_B);
args->current_id++;
}
@@ -593,13 +624,27 @@ run_chunk_sizes(cmd_args_t *args)
return (rc);
}
static int
run_block_sizes(cmd_args_t *args)
{
int rc = 0;
while (rc == 0 && get_next(&args->current_B, &args->B)) {
rc = run_chunk_sizes(args);
}
args->B.next_val = 0;
return (rc);
}
static int
run_thread_counts(cmd_args_t *args)
{
int rc = 0;
while (rc == 0 && get_next((uint64_t *)&args->current_T, &args->T))
rc = run_chunk_sizes(args);
rc = run_block_sizes(args);
return (rc);
}
+14 -5
View File
@@ -29,6 +29,8 @@
*
* You should have received a copy of the GNU General Public License along
* with ZPIOS. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (c) 2015, Intel Corporation.
*/
#include <stdlib.h>
@@ -185,6 +187,8 @@ int
set_count(char *pattern1, char *pattern2, range_repeat_t *range,
char *optarg, uint32_t *flags, char *arg)
{
uint64_t count = range->val_count;
if (flags)
*flags |= FLAG_SET;
@@ -197,6 +201,9 @@ set_count(char *pattern1, char *pattern2, range_repeat_t *range,
fprintf(stderr, "Error: Incorrect pattern for %s, '%s'\n",
arg, optarg);
return (EINVAL);
} else if (count == range->val_count) {
fprintf(stderr, "Error: input ignored for %s, '%s'\n",
arg, optarg);
}
return (0);
@@ -314,14 +321,14 @@ print_stats_header(cmd_args_t *args)
if (args->verbose) {
printf(
"status name id\tth-cnt\trg-cnt\trg-sz\t"
"ch-sz\toffset\trg-no\tch-no\tth-dly\tflags\ttime\t"
"ch-sz\toffset\trg-no\tch-no\tth-dly\tflags\tblksz\ttime\t"
"cr-time\trm-time\twr-time\trd-time\twr-data\twr-ch\t"
"wr-bw\trd-data\trd-ch\trd-bw\n");
printf(
"------------------------------------------------"
"------------------------------------------------"
"------------------------------------------------"
"----------------------------------------------\n");
"-------------------------------------------------"
"-------------------------------------------------"
"-------------------------------------------------"
"--------------------------------------------------\n");
} else {
printf(
"status name id\t"
@@ -358,6 +365,7 @@ print_stats_human_readable(cmd_args_t *args, zpios_cmd_t *cmd)
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_chunk_noise));
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_thread_delay));
printf("%s\t", print_flags(str, cmd->cmd_flags));
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_block_size));
}
if (args->rc) {
@@ -414,6 +422,7 @@ print_stats_table(cmd_args_t *args, zpios_cmd_t *cmd)
printf("%u\t", cmd->cmd_chunk_noise);
printf("%u\t", cmd->cmd_thread_delay);
printf("0x%x\t", cmd->cmd_flags);
printf("%u\t", cmd->cmd_block_size);
}
if (args->rc) {