Skip to content

Commit

Permalink
12668 ZFS support for vectorized algorithms on x86 (initial support)
Browse files Browse the repository at this point in the history
Portions contributed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed by: Jason King <jason.king@joyent.com>
Approved by: Dan McDonald <danmcd@joyent.com>
  • Loading branch information
ironMann authored and jjelinek committed Jun 1, 2020
1 parent 82049ff commit e86372a
Show file tree
Hide file tree
Showing 29 changed files with 4,464 additions and 192 deletions.
1 change: 1 addition & 0 deletions exception_lists/check_rtime
Expand Up @@ -231,6 +231,7 @@ FORBIDDEN libfakekernel\.so
FORBIDDEN_DEP usr/MACH(lib)/libzpool.so.1
FORBIDDEN_DEP usr/bin/amd64/ztest
FORBIDDEN_DEP usr/bin/i86/ztest
FORBIDDEN_DEP usr/bin/raidz_test
FORBIDDEN_DEP usr/bin/sparcv7/ztest
FORBIDDEN_DEP usr/bin/sparcv9/ztest
FORBIDDEN_DEP usr/lib/MACH(smbfs)/libfknsmb.so.1
Expand Down
3 changes: 2 additions & 1 deletion usr/src/cmd/Makefile
Expand Up @@ -21,7 +21,7 @@

#
# Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright 2019 Joyent, Inc.
# Copyright 2020 Joyent, Inc.
# Copyright (c) 2012, 2015 by Delphix. All rights reserved.
# Copyright (c) 2013 DEY Storage Systems, Inc. All rights reserved.
# Copyright 2014 Garrett D'Amore <garrett@damore.org>
Expand Down Expand Up @@ -346,6 +346,7 @@ COMMON_SUBDIRS= \
pwd \
pyzfs \
raidctl \
raidz_test \
ramdiskadm \
rcap \
rcm_daemon \
Expand Down
61 changes: 61 additions & 0 deletions usr/src/cmd/raidz_test/Makefile
@@ -0,0 +1,61 @@
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#

#
# Copyright 2020 Joyent, Inc.
#

include ../Makefile.cmd
include ../Makefile.cmd.64

PROG= raidz_test
OBJS= raidz_test.o raidz_bench.o
SRCS= $(OBJS:%.o=%.c)
POFILES= $(PROG:%=%.po)

# No msg catalog here.
POFILE=

LDLIBS += -lzpool -lfakekernel -lumem

INCS += -I../../lib/libzpool/common
INCS += -I../../uts/common/fs/zfs

CPPFLAGS.first = -I$(SRC)/lib/libfakekernel/common -D_FAKE_KERNEL
CPPFLAGS += -D_LARGEFILE64_SOURCE=1
CPPFLAGS += $(INCS)

CSTD = $(CSTD_GNU99)

CERRWARN += -_gcc=-Wno-type-limits

SMATCH=off

.KEEP_STATE:

all: $(PROG)

$(PROG): $(OBJS)
$(LINK.c) -o $(PROG) $(OBJS) $(LDLIBS)
$(POST_PROCESS)

install: all $(ROOTPROG)

clean:
$(RM) $(OBJS)

_msg: $(MSGDOMAIN) $(POFILES)
$(CP) $(POFILES) $(MSGDOMAIN)

$(MSGDOMAIN):
$(INS.dir)

include ../Makefile.targ
228 changes: 228 additions & 0 deletions usr/src/cmd/raidz_test/raidz_bench.c
@@ -0,0 +1,228 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/

/*
* Copyright (C) 2016 Gvozden Nešković. All rights reserved.
*/

#include <sys/zfs_context.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/zio.h>
#include <sys/vdev_raidz.h>
#include <sys/vdev_raidz_impl.h>
#include <stdio.h>
#include <strings.h>

#include <sys/time.h>

#include "raidz_test.h"

#define GEN_BENCH_MEMORY (((uint64_t)1ULL)<<32)
#define REC_BENCH_MEMORY (((uint64_t)1ULL)<<29)
#define BENCH_ASHIFT 12
#define MIN_CS_SHIFT BENCH_ASHIFT
#define MAX_CS_SHIFT SPA_MAXBLOCKSHIFT

static zio_t zio_bench;
static raidz_map_t *rm_bench;
static size_t max_data_size = SPA_MAXBLOCKSIZE;

static void
bench_init_raidz_map(void)
{
zio_bench.io_offset = 0;
zio_bench.io_size = max_data_size;

/*
* To permit larger column sizes these have to be done
* allocated using aligned alloc instead of zio_abd_buf_alloc
*/
zio_bench.io_abd = raidz_alloc(max_data_size);

init_zio_abd(&zio_bench);
}

static void
bench_fini_raidz_maps(void)
{
/* tear down golden zio */
raidz_free(zio_bench.io_abd, max_data_size);
bzero(&zio_bench, sizeof (zio_t));
}

static inline void
run_gen_bench_impl(const char *impl)
{
int fn, ncols;
uint64_t ds, iter_cnt, iter, disksize;
hrtime_t start;
double elapsed, d_bw;

/* Benchmark generate functions */
for (fn = 0; fn < RAIDZ_GEN_NUM; fn++) {

for (ds = MIN_CS_SHIFT; ds <= MAX_CS_SHIFT; ds++) {
/* create suitable raidz_map */
ncols = rto_opts.rto_dcols + fn + 1;
zio_bench.io_size = 1ULL << ds;
rm_bench = vdev_raidz_map_alloc(&zio_bench,
BENCH_ASHIFT, ncols, fn+1);

/* estimate iteration count */
iter_cnt = GEN_BENCH_MEMORY;
iter_cnt /= zio_bench.io_size;

start = gethrtime();
for (iter = 0; iter < iter_cnt; iter++)
vdev_raidz_generate_parity(rm_bench);
elapsed = NSEC2SEC((double)(gethrtime() - start));

disksize = (1ULL << ds) / rto_opts.rto_dcols;
d_bw = (double)iter_cnt * (double)disksize;
d_bw /= (1024.0 * 1024.0 * elapsed);

LOG(D_ALL, "%10s, %8s, %zu, %10llu, %lf, %lf, %u\n",
impl,
raidz_gen_name[fn],
rto_opts.rto_dcols,
(1ULL<<ds),
d_bw,
d_bw * (double)(ncols),
(unsigned)iter_cnt);

vdev_raidz_map_free(rm_bench);
}
}
}

void
run_gen_bench(void)
{
char **impl_name;

LOG(D_INFO, DBLSEP "\nBenchmarking parity generation...\n\n");
LOG(D_ALL, "impl, math, dcols, iosize, disk_bw, total_bw, iter\n");

for (impl_name = (char **)raidz_impl_names; *impl_name != NULL;
impl_name++) {

if (vdev_raidz_impl_set(*impl_name) != 0)
continue;

run_gen_bench_impl(*impl_name);
}
}

static void
run_rec_bench_impl(const char *impl)
{
int fn, ncols, nbad;
uint64_t ds, iter_cnt, iter, disksize;
hrtime_t start;
double elapsed, d_bw;
static const int tgt[7][3] = {
{1, 2, 3}, /* rec_p: bad QR & D[0] */
{0, 2, 3}, /* rec_q: bad PR & D[0] */
{0, 1, 3}, /* rec_r: bad PQ & D[0] */
{2, 3, 4}, /* rec_pq: bad R & D[0][1] */
{1, 3, 4}, /* rec_pr: bad Q & D[0][1] */
{0, 3, 4}, /* rec_qr: bad P & D[0][1] */
{3, 4, 5} /* rec_pqr: bad & D[0][1][2] */
};

for (fn = 0; fn < RAIDZ_REC_NUM; fn++) {
for (ds = MIN_CS_SHIFT; ds <= MAX_CS_SHIFT; ds++) {

/* create suitable raidz_map */
ncols = rto_opts.rto_dcols + PARITY_PQR;
zio_bench.io_size = 1ULL << ds;

/*
* raidz block is too short to test
* the requested method
*/
if (zio_bench.io_size / rto_opts.rto_dcols <
(1ULL << BENCH_ASHIFT))
continue;

rm_bench = vdev_raidz_map_alloc(&zio_bench,
BENCH_ASHIFT, ncols, PARITY_PQR);

/* estimate iteration count */
iter_cnt = (REC_BENCH_MEMORY);
iter_cnt /= zio_bench.io_size;

/* calculate how many bad columns there are */
nbad = MIN(3, raidz_ncols(rm_bench) -
raidz_parity(rm_bench));

start = gethrtime();
for (iter = 0; iter < iter_cnt; iter++)
vdev_raidz_reconstruct(rm_bench, tgt[fn], nbad);
elapsed = NSEC2SEC((double)(gethrtime() - start));

disksize = (1ULL << ds) / rto_opts.rto_dcols;
d_bw = (double)iter_cnt * (double)(disksize);
d_bw /= (1024.0 * 1024.0 * elapsed);

LOG(D_ALL, "%10s, %8s, %zu, %10llu, %lf, %lf, %u\n",
impl,
raidz_rec_name[fn],
rto_opts.rto_dcols,
(1ULL<<ds),
d_bw,
d_bw * (double)ncols,
(unsigned)iter_cnt);

vdev_raidz_map_free(rm_bench);
}
}
}

void
run_rec_bench(void)
{
char **impl_name;

LOG(D_INFO, DBLSEP "\nBenchmarking data reconstruction...\n\n");
LOG(D_ALL, "impl, math, dcols, iosize, disk_bw, total_bw, iter\n");

for (impl_name = (char **)raidz_impl_names; *impl_name != NULL;
impl_name++) {

if (vdev_raidz_impl_set(*impl_name) != 0)
continue;

run_rec_bench_impl(*impl_name);
}
}

void
run_raidz_benchmark(void)
{
bench_init_raidz_map();

run_gen_bench();
run_rec_bench();

bench_fini_raidz_maps();
}

0 comments on commit e86372a

Please sign in to comment.