Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/cmd/raidz_test/raidz_bench.c
48380 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* CDDL HEADER START
4
*
5
* The contents of this file are subject to the terms of the
6
* Common Development and Distribution License (the "License").
7
* You may not use this file except in compliance with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or https://opensource.org/licenses/CDDL-1.0.
11
* See the License for the specific language governing permissions
12
* and limitations under the License.
13
*
14
* When distributing Covered Code, include this CDDL HEADER in each
15
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16
* If applicable, add the following below this CDDL HEADER, with the
17
* fields enclosed by brackets "[]" replaced with your own identifying
18
* information: Portions Copyright [yyyy] [name of copyright owner]
19
*
20
* CDDL HEADER END
21
*/
22
23
/*
24
* Copyright (C) 2016 Gvozden Nešković. All rights reserved.
25
*/
26
27
#include <sys/zfs_context.h>
28
#include <sys/time.h>
29
#include <sys/wait.h>
30
#include <sys/zio.h>
31
#include <sys/vdev_raidz.h>
32
#include <sys/vdev_raidz_impl.h>
33
#include <stdio.h>
34
35
#include "raidz_test.h"
36
37
#define GEN_BENCH_MEMORY (((uint64_t)1ULL)<<32)
38
#define REC_BENCH_MEMORY (((uint64_t)1ULL)<<29)
39
#define BENCH_ASHIFT 12
40
#define MIN_CS_SHIFT BENCH_ASHIFT
41
#define MAX_CS_SHIFT SPA_MAXBLOCKSHIFT
42
43
static zio_t zio_bench;
44
static raidz_map_t *rm_bench;
45
static size_t max_data_size = SPA_MAXBLOCKSIZE;
46
47
static void
48
bench_init_raidz_map(void)
49
{
50
zio_bench.io_offset = 0;
51
zio_bench.io_size = max_data_size;
52
53
/*
54
* To permit larger column sizes these have to be done
55
* allocated using aligned alloc instead of zio_abd_buf_alloc
56
*/
57
zio_bench.io_abd = raidz_alloc(max_data_size);
58
59
init_zio_abd(&zio_bench);
60
}
61
62
static void
63
bench_fini_raidz_maps(void)
64
{
65
/* tear down golden zio */
66
raidz_free(zio_bench.io_abd, max_data_size);
67
memset(&zio_bench, 0, sizeof (zio_t));
68
}
69
70
static inline void
71
run_gen_bench_impl(const char *impl)
72
{
73
int fn, ncols;
74
uint64_t ds, iter_cnt, iter, disksize;
75
hrtime_t start;
76
double elapsed, d_bw;
77
78
/* Benchmark generate functions */
79
for (fn = 0; fn < RAIDZ_GEN_NUM; fn++) {
80
81
for (ds = MIN_CS_SHIFT; ds <= MAX_CS_SHIFT; ds++) {
82
/* create suitable raidz_map */
83
ncols = rto_opts.rto_dcols + fn + 1;
84
zio_bench.io_size = 1ULL << ds;
85
86
if (rto_opts.rto_expand) {
87
rm_bench = vdev_raidz_map_alloc_expanded(
88
&zio_bench,
89
rto_opts.rto_ashift, ncols+1, ncols,
90
fn+1, rto_opts.rto_expand_offset,
91
0, B_FALSE);
92
} else {
93
rm_bench = vdev_raidz_map_alloc(&zio_bench,
94
BENCH_ASHIFT, ncols, fn+1);
95
}
96
97
/* estimate iteration count */
98
iter_cnt = GEN_BENCH_MEMORY;
99
iter_cnt /= zio_bench.io_size;
100
101
start = gethrtime();
102
for (iter = 0; iter < iter_cnt; iter++)
103
vdev_raidz_generate_parity(rm_bench);
104
elapsed = NSEC2SEC((double)(gethrtime() - start));
105
106
disksize = (1ULL << ds) / rto_opts.rto_dcols;
107
d_bw = (double)iter_cnt * (double)disksize;
108
d_bw /= (1024.0 * 1024.0 * elapsed);
109
110
LOG(D_ALL, "%10s, %8s, %zu, %10llu, %lf, %lf, %u\n",
111
impl,
112
raidz_gen_name[fn],
113
rto_opts.rto_dcols,
114
(1ULL<<ds),
115
d_bw,
116
d_bw * (double)(ncols),
117
(unsigned)iter_cnt);
118
119
vdev_raidz_map_free(rm_bench);
120
}
121
}
122
}
123
124
static void
125
run_gen_bench(void)
126
{
127
char **impl_name;
128
129
LOG(D_INFO, DBLSEP "\nBenchmarking parity generation...\n\n");
130
LOG(D_ALL, "impl, math, dcols, iosize, disk_bw, total_bw, iter\n");
131
132
for (impl_name = (char **)raidz_impl_names; *impl_name != NULL;
133
impl_name++) {
134
135
if (vdev_raidz_impl_set(*impl_name) != 0)
136
continue;
137
138
run_gen_bench_impl(*impl_name);
139
}
140
}
141
142
static void
143
run_rec_bench_impl(const char *impl)
144
{
145
int fn, ncols, nbad;
146
uint64_t ds, iter_cnt, iter, disksize;
147
hrtime_t start;
148
double elapsed, d_bw;
149
static const int tgt[7][3] = {
150
{1, 2, 3}, /* rec_p: bad QR & D[0] */
151
{0, 2, 3}, /* rec_q: bad PR & D[0] */
152
{0, 1, 3}, /* rec_r: bad PQ & D[0] */
153
{2, 3, 4}, /* rec_pq: bad R & D[0][1] */
154
{1, 3, 4}, /* rec_pr: bad Q & D[0][1] */
155
{0, 3, 4}, /* rec_qr: bad P & D[0][1] */
156
{3, 4, 5} /* rec_pqr: bad & D[0][1][2] */
157
};
158
159
for (fn = 0; fn < RAIDZ_REC_NUM; fn++) {
160
for (ds = MIN_CS_SHIFT; ds <= MAX_CS_SHIFT; ds++) {
161
162
/* create suitable raidz_map */
163
ncols = rto_opts.rto_dcols + PARITY_PQR;
164
zio_bench.io_size = 1ULL << ds;
165
166
/*
167
* raidz block is too short to test
168
* the requested method
169
*/
170
if (zio_bench.io_size / rto_opts.rto_dcols <
171
(1ULL << BENCH_ASHIFT))
172
continue;
173
174
if (rto_opts.rto_expand) {
175
rm_bench = vdev_raidz_map_alloc_expanded(
176
&zio_bench,
177
BENCH_ASHIFT, ncols+1, ncols,
178
PARITY_PQR,
179
rto_opts.rto_expand_offset, 0, B_FALSE);
180
} else {
181
rm_bench = vdev_raidz_map_alloc(&zio_bench,
182
BENCH_ASHIFT, ncols, PARITY_PQR);
183
}
184
185
/* estimate iteration count */
186
iter_cnt = (REC_BENCH_MEMORY);
187
iter_cnt /= zio_bench.io_size;
188
189
/* calculate how many bad columns there are */
190
nbad = MIN(3, raidz_ncols(rm_bench) -
191
raidz_parity(rm_bench));
192
193
start = gethrtime();
194
for (iter = 0; iter < iter_cnt; iter++)
195
vdev_raidz_reconstruct(rm_bench, tgt[fn], nbad);
196
elapsed = NSEC2SEC((double)(gethrtime() - start));
197
198
disksize = (1ULL << ds) / rto_opts.rto_dcols;
199
d_bw = (double)iter_cnt * (double)(disksize);
200
d_bw /= (1024.0 * 1024.0 * elapsed);
201
202
LOG(D_ALL, "%10s, %8s, %zu, %10llu, %lf, %lf, %u\n",
203
impl,
204
raidz_rec_name[fn],
205
rto_opts.rto_dcols,
206
(1ULL<<ds),
207
d_bw,
208
d_bw * (double)ncols,
209
(unsigned)iter_cnt);
210
211
vdev_raidz_map_free(rm_bench);
212
}
213
}
214
}
215
216
static void
217
run_rec_bench(void)
218
{
219
char **impl_name;
220
221
LOG(D_INFO, DBLSEP "\nBenchmarking data reconstruction...\n\n");
222
LOG(D_ALL, "impl, math, dcols, iosize, disk_bw, total_bw, iter\n");
223
224
for (impl_name = (char **)raidz_impl_names; *impl_name != NULL;
225
impl_name++) {
226
227
if (vdev_raidz_impl_set(*impl_name) != 0)
228
continue;
229
230
run_rec_bench_impl(*impl_name);
231
}
232
}
233
234
void
235
run_raidz_benchmark(void)
236
{
237
bench_init_raidz_map();
238
239
run_gen_bench();
240
run_rec_bench();
241
242
bench_fini_raidz_maps();
243
}
244
245