]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - cmd/raidz_test/raidz_bench.c
Use abs_top_builddir when referencing libraries
[FreeBSD/FreeBSD.git] / cmd / raidz_test / raidz_bench.c
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21
22 /*
23  * Copyright (C) 2016 Gvozden Nešković. All rights reserved.
24  */
25
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>
33
34 #include <sys/time.h>
35
36 #include "raidz_test.h"
37
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
43
44 static zio_t zio_bench;
45 static raidz_map_t *rm_bench;
46 static size_t max_data_size = SPA_MAXBLOCKSIZE;
47
48 static void
49 bench_init_raidz_map(void)
50 {
51         zio_bench.io_offset = 0;
52         zio_bench.io_size = max_data_size;
53
54         /*
55          * To permit larger column sizes these have to be done
56          * allocated using aligned alloc instead of zio_abd_buf_alloc
57          */
58         zio_bench.io_abd = raidz_alloc(max_data_size);
59
60         init_zio_abd(&zio_bench);
61 }
62
63 static void
64 bench_fini_raidz_maps(void)
65 {
66         /* tear down golden zio */
67         raidz_free(zio_bench.io_abd, max_data_size);
68         bzero(&zio_bench, sizeof (zio_t));
69 }
70
71 static inline void
72 run_gen_bench_impl(const char *impl)
73 {
74         int fn, ncols;
75         uint64_t ds, iter_cnt, iter, disksize;
76         hrtime_t start;
77         double elapsed, d_bw;
78
79         /* Benchmark generate functions */
80         for (fn = 0; fn < RAIDZ_GEN_NUM; fn++) {
81
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;
86                         rm_bench = vdev_raidz_map_alloc(&zio_bench,
87                             BENCH_ASHIFT, ncols, fn+1);
88
89                         /* estimate iteration count */
90                         iter_cnt = GEN_BENCH_MEMORY;
91                         iter_cnt /= zio_bench.io_size;
92
93                         start = gethrtime();
94                         for (iter = 0; iter < iter_cnt; iter++)
95                                 vdev_raidz_generate_parity(rm_bench);
96                         elapsed = NSEC2SEC((double)(gethrtime() - start));
97
98                         disksize = (1ULL << ds) / rto_opts.rto_dcols;
99                         d_bw = (double)iter_cnt * (double)disksize;
100                         d_bw /= (1024.0 * 1024.0 * elapsed);
101
102                         LOG(D_ALL, "%10s, %8s, %zu, %10llu, %lf, %lf, %u\n",
103                             impl,
104                             raidz_gen_name[fn],
105                             rto_opts.rto_dcols,
106                             (1ULL<<ds),
107                             d_bw,
108                             d_bw * (double)(ncols),
109                             (unsigned)iter_cnt);
110
111                         vdev_raidz_map_free(rm_bench);
112                 }
113         }
114 }
115
116 static void
117 run_gen_bench(void)
118 {
119         char **impl_name;
120
121         LOG(D_INFO, DBLSEP "\nBenchmarking parity generation...\n\n");
122         LOG(D_ALL, "impl, math, dcols, iosize, disk_bw, total_bw, iter\n");
123
124         for (impl_name = (char **)raidz_impl_names; *impl_name != NULL;
125             impl_name++) {
126
127                 if (vdev_raidz_impl_set(*impl_name) != 0)
128                         continue;
129
130                 run_gen_bench_impl(*impl_name);
131         }
132 }
133
134 static void
135 run_rec_bench_impl(const char *impl)
136 {
137         int fn, ncols, nbad;
138         uint64_t ds, iter_cnt, iter, disksize;
139         hrtime_t start;
140         double elapsed, d_bw;
141         static const int tgt[7][3] = {
142                 {1, 2, 3},      /* rec_p:   bad QR & D[0]       */
143                 {0, 2, 3},      /* rec_q:   bad PR & D[0]       */
144                 {0, 1, 3},      /* rec_r:   bad PQ & D[0]       */
145                 {2, 3, 4},      /* rec_pq:  bad R  & D[0][1]    */
146                 {1, 3, 4},      /* rec_pr:  bad Q  & D[0][1]    */
147                 {0, 3, 4},      /* rec_qr:  bad P  & D[0][1]    */
148                 {3, 4, 5}       /* rec_pqr: bad    & D[0][1][2] */
149         };
150
151         for (fn = 0; fn < RAIDZ_REC_NUM; fn++) {
152                 for (ds = MIN_CS_SHIFT; ds <= MAX_CS_SHIFT; ds++) {
153
154                         /* create suitable raidz_map */
155                         ncols = rto_opts.rto_dcols + PARITY_PQR;
156                         zio_bench.io_size = 1ULL << ds;
157
158                         /*
159                          * raidz block is too short to test
160                          * the requested method
161                          */
162                         if (zio_bench.io_size / rto_opts.rto_dcols <
163                             (1ULL << BENCH_ASHIFT))
164                                 continue;
165
166                         rm_bench = vdev_raidz_map_alloc(&zio_bench,
167                             BENCH_ASHIFT, ncols, PARITY_PQR);
168
169                         /* estimate iteration count */
170                         iter_cnt = (REC_BENCH_MEMORY);
171                         iter_cnt /= zio_bench.io_size;
172
173                         /* calculate how many bad columns there are */
174                         nbad = MIN(3, raidz_ncols(rm_bench) -
175                             raidz_parity(rm_bench));
176
177                         start = gethrtime();
178                         for (iter = 0; iter < iter_cnt; iter++)
179                                 vdev_raidz_reconstruct(rm_bench, tgt[fn], nbad);
180                         elapsed = NSEC2SEC((double)(gethrtime() - start));
181
182                         disksize = (1ULL << ds) / rto_opts.rto_dcols;
183                         d_bw = (double)iter_cnt * (double)(disksize);
184                         d_bw /= (1024.0 * 1024.0 * elapsed);
185
186                         LOG(D_ALL, "%10s, %8s, %zu, %10llu, %lf, %lf, %u\n",
187                             impl,
188                             raidz_rec_name[fn],
189                             rto_opts.rto_dcols,
190                             (1ULL<<ds),
191                             d_bw,
192                             d_bw * (double)ncols,
193                             (unsigned)iter_cnt);
194
195                         vdev_raidz_map_free(rm_bench);
196                 }
197         }
198 }
199
200 static void
201 run_rec_bench(void)
202 {
203         char **impl_name;
204
205         LOG(D_INFO, DBLSEP "\nBenchmarking data reconstruction...\n\n");
206         LOG(D_ALL, "impl, math, dcols, iosize, disk_bw, total_bw, iter\n");
207
208         for (impl_name = (char **)raidz_impl_names; *impl_name != NULL;
209             impl_name++) {
210
211                 if (vdev_raidz_impl_set(*impl_name) != 0)
212                         continue;
213
214                 run_rec_bench_impl(*impl_name);
215         }
216 }
217
218 void
219 run_raidz_benchmark(void)
220 {
221         bench_init_raidz_map();
222
223         run_gen_bench();
224         run_rec_bench();
225
226         bench_fini_raidz_maps();
227 }