Add "compatibility" property for zpool feature sets
[zfs.git] / cmd / raidz_test / raidz_bench.c
bloba3446c52c4162b91e68f93cb02e0e55bfc41b665
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (C) 2016 Gvozden Nešković. All rights reserved.
26 #include <sys/zfs_context.h>
27 #include <sys/time.h>
28 #include <sys/wait.h>
29 #include <sys/zio.h>
30 #include <sys/vdev_raidz.h>
31 #include <sys/vdev_raidz_impl.h>
32 #include <stdio.h>
34 #include <sys/time.h>
36 #include "raidz_test.h"
38 #define GEN_BENCH_MEMORY (((uint64_t)1ULL)<<32)
39 #define REC_BENCH_MEMORY (((uint64_t)1ULL)<<29)
40 #define BENCH_ASHIFT 12
41 #define MIN_CS_SHIFT BENCH_ASHIFT
42 #define MAX_CS_SHIFT SPA_MAXBLOCKSHIFT
44 static zio_t zio_bench;
45 static raidz_map_t *rm_bench;
46 static size_t max_data_size = SPA_MAXBLOCKSIZE;
48 static void
49 bench_init_raidz_map(void)
51 zio_bench.io_offset = 0;
52 zio_bench.io_size = max_data_size;
55 * To permit larger column sizes these have to be done
56 * allocated using aligned alloc instead of zio_abd_buf_alloc
58 zio_bench.io_abd = raidz_alloc(max_data_size);
60 init_zio_abd(&zio_bench);
63 static void
64 bench_fini_raidz_maps(void)
66 /* tear down golden zio */
67 raidz_free(zio_bench.io_abd, max_data_size);
68 bzero(&zio_bench, sizeof (zio_t));
71 static inline void
72 run_gen_bench_impl(const char *impl)
74 int fn, ncols;
75 uint64_t ds, iter_cnt, iter, disksize;
76 hrtime_t start;
77 double elapsed, d_bw;
79 /* Benchmark generate functions */
80 for (fn = 0; fn < RAIDZ_GEN_NUM; fn++) {
82 for (ds = MIN_CS_SHIFT; ds <= MAX_CS_SHIFT; ds++) {
83 /* create suitable raidz_map */
84 ncols = rto_opts.rto_dcols + fn + 1;
85 zio_bench.io_size = 1ULL << ds;
87 if (rto_opts.rto_expand) {
88 rm_bench = vdev_raidz_map_alloc_expanded(
89 zio_bench.io_abd,
90 zio_bench.io_size, zio_bench.io_offset,
91 rto_opts.rto_ashift, ncols+1, ncols,
92 fn+1, rto_opts.rto_expand_offset);
93 } else {
94 rm_bench = vdev_raidz_map_alloc(&zio_bench,
95 BENCH_ASHIFT, ncols, fn+1);
98 /* estimate iteration count */
99 iter_cnt = GEN_BENCH_MEMORY;
100 iter_cnt /= zio_bench.io_size;
102 start = gethrtime();
103 for (iter = 0; iter < iter_cnt; iter++)
104 vdev_raidz_generate_parity(rm_bench);
105 elapsed = NSEC2SEC((double)(gethrtime() - start));
107 disksize = (1ULL << ds) / rto_opts.rto_dcols;
108 d_bw = (double)iter_cnt * (double)disksize;
109 d_bw /= (1024.0 * 1024.0 * elapsed);
111 LOG(D_ALL, "%10s, %8s, %zu, %10llu, %lf, %lf, %u\n",
112 impl,
113 raidz_gen_name[fn],
114 rto_opts.rto_dcols,
115 (1ULL<<ds),
116 d_bw,
117 d_bw * (double)(ncols),
118 (unsigned)iter_cnt);
120 vdev_raidz_map_free(rm_bench);
125 static void
126 run_gen_bench(void)
128 char **impl_name;
130 LOG(D_INFO, DBLSEP "\nBenchmarking parity generation...\n\n");
131 LOG(D_ALL, "impl, math, dcols, iosize, disk_bw, total_bw, iter\n");
133 for (impl_name = (char **)raidz_impl_names; *impl_name != NULL;
134 impl_name++) {
136 if (vdev_raidz_impl_set(*impl_name) != 0)
137 continue;
139 run_gen_bench_impl(*impl_name);
143 static void
144 run_rec_bench_impl(const char *impl)
146 int fn, ncols, nbad;
147 uint64_t ds, iter_cnt, iter, disksize;
148 hrtime_t start;
149 double elapsed, d_bw;
150 static const int tgt[7][3] = {
151 {1, 2, 3}, /* rec_p: bad QR & D[0] */
152 {0, 2, 3}, /* rec_q: bad PR & D[0] */
153 {0, 1, 3}, /* rec_r: bad PQ & D[0] */
154 {2, 3, 4}, /* rec_pq: bad R & D[0][1] */
155 {1, 3, 4}, /* rec_pr: bad Q & D[0][1] */
156 {0, 3, 4}, /* rec_qr: bad P & D[0][1] */
157 {3, 4, 5} /* rec_pqr: bad & D[0][1][2] */
160 for (fn = 0; fn < RAIDZ_REC_NUM; fn++) {
161 for (ds = MIN_CS_SHIFT; ds <= MAX_CS_SHIFT; ds++) {
163 /* create suitable raidz_map */
164 ncols = rto_opts.rto_dcols + PARITY_PQR;
165 zio_bench.io_size = 1ULL << ds;
168 * raidz block is too short to test
169 * the requested method
171 if (zio_bench.io_size / rto_opts.rto_dcols <
172 (1ULL << BENCH_ASHIFT))
173 continue;
175 if (rto_opts.rto_expand) {
176 rm_bench = vdev_raidz_map_alloc_expanded(
177 zio_bench.io_abd,
178 zio_bench.io_size, zio_bench.io_offset,
179 BENCH_ASHIFT, ncols+1, ncols,
180 PARITY_PQR, rto_opts.rto_expand_offset);
181 } else {
182 rm_bench = vdev_raidz_map_alloc(&zio_bench,
183 BENCH_ASHIFT, ncols, PARITY_PQR);
186 /* estimate iteration count */
187 iter_cnt = (REC_BENCH_MEMORY);
188 iter_cnt /= zio_bench.io_size;
190 /* calculate how many bad columns there are */
191 nbad = MIN(3, raidz_ncols(rm_bench) -
192 raidz_parity(rm_bench));
194 start = gethrtime();
195 for (iter = 0; iter < iter_cnt; iter++)
196 vdev_raidz_reconstruct(rm_bench, tgt[fn], nbad);
197 elapsed = NSEC2SEC((double)(gethrtime() - start));
199 disksize = (1ULL << ds) / rto_opts.rto_dcols;
200 d_bw = (double)iter_cnt * (double)(disksize);
201 d_bw /= (1024.0 * 1024.0 * elapsed);
203 LOG(D_ALL, "%10s, %8s, %zu, %10llu, %lf, %lf, %u\n",
204 impl,
205 raidz_rec_name[fn],
206 rto_opts.rto_dcols,
207 (1ULL<<ds),
208 d_bw,
209 d_bw * (double)ncols,
210 (unsigned)iter_cnt);
212 vdev_raidz_map_free(rm_bench);
217 static void
218 run_rec_bench(void)
220 char **impl_name;
222 LOG(D_INFO, DBLSEP "\nBenchmarking data reconstruction...\n\n");
223 LOG(D_ALL, "impl, math, dcols, iosize, disk_bw, total_bw, iter\n");
225 for (impl_name = (char **)raidz_impl_names; *impl_name != NULL;
226 impl_name++) {
228 if (vdev_raidz_impl_set(*impl_name) != 0)
229 continue;
231 run_rec_bench_impl(*impl_name);
235 void
236 run_raidz_benchmark(void)
238 bench_init_raidz_map();
240 run_gen_bench();
241 run_rec_bench();
243 bench_fini_raidz_maps();