cubefs

Форк
0
277 строк · 8.5 Кб
1
package reedsolomon
2

3
import (
4
	"runtime"
5

6
	"github.com/klauspost/cpuid/v2"
7
)
8

9
// Option allows to override processing parameters.
10
type Option func(*options)
11

12
type options struct {
13
	maxGoroutines int
14
	minSplitSize  int
15
	shardSize     int
16
	perRound      int
17

18
	useGFNI, useAVX512, useAVX2, useSSSE3, useSSE2 bool
19
	useJerasureMatrix                              bool
20
	usePAR1Matrix                                  bool
21
	useCauchy                                      bool
22
	fastOneParity                                  bool
23
	inversionCache                                 bool
24
	forcedInversionCache                           bool
25
	customMatrix                                   [][]byte
26
	withLeopard                                    leopardMode
27

28
	// stream options
29
	concReads  bool
30
	concWrites bool
31
	streamBS   int
32
}
33

34
var defaultOptions = options{
35
	maxGoroutines:  384,
36
	minSplitSize:   -1,
37
	fastOneParity:  false,
38
	inversionCache: true,
39

40
	// Detect CPU capabilities.
41
	useSSSE3:  cpuid.CPU.Supports(cpuid.SSSE3),
42
	useSSE2:   cpuid.CPU.Supports(cpuid.SSE2),
43
	useAVX2:   cpuid.CPU.Supports(cpuid.AVX2),
44
	useAVX512: cpuid.CPU.Supports(cpuid.AVX512F, cpuid.AVX512BW, cpuid.AVX512VL),
45
	useGFNI:   cpuid.CPU.Supports(cpuid.AVX512F, cpuid.GFNI, cpuid.AVX512DQ),
46
}
47

48
// leopardMode controls the use of leopard GF in encoding and decoding.
49
type leopardMode int
50

51
const (
52
	// leopardAsNeeded only switches to leopard 16-bit when there are more than
53
	// 256 shards.
54
	leopardAsNeeded leopardMode = iota
55
	// leopardGF16 uses leopard in 16-bit mode for all shard counts.
56
	leopardGF16
57
	// leopardAlways uses 8-bit leopard for shards less than or equal to 256,
58
	// 16-bit leopard otherwise.
59
	leopardAlways
60
)
61

62
func init() {
63
	if runtime.GOMAXPROCS(0) <= 1 {
64
		defaultOptions.maxGoroutines = 1
65
	}
66
}
67

68
// WithMaxGoroutines is the maximum number of goroutines number for encoding & decoding.
69
// Jobs will be split into this many parts, unless each goroutine would have to process
70
// less than minSplitSize bytes (set with WithMinSplitSize).
71
// For the best speed, keep this well above the GOMAXPROCS number for more fine grained
72
// scheduling.
73
// If n <= 0, it is ignored.
74
func WithMaxGoroutines(n int) Option {
75
	return func(o *options) {
76
		if n > 0 {
77
			o.maxGoroutines = n
78
		}
79
	}
80
}
81

82
// WithAutoGoroutines will adjust the number of goroutines for optimal speed with a
83
// specific shard size.
84
// Send in the shard size you expect to send. Other shard sizes will work, but may not
85
// run at the optimal speed.
86
// Overwrites WithMaxGoroutines.
87
// If shardSize <= 0, it is ignored.
88
func WithAutoGoroutines(shardSize int) Option {
89
	return func(o *options) {
90
		o.shardSize = shardSize
91
	}
92
}
93

94
// WithMinSplitSize is the minimum encoding size in bytes per goroutine.
95
// By default this parameter is determined by CPU cache characteristics.
96
// See WithMaxGoroutines on how jobs are split.
97
// If n <= 0, it is ignored.
98
func WithMinSplitSize(n int) Option {
99
	return func(o *options) {
100
		if n > 0 {
101
			o.minSplitSize = n
102
		}
103
	}
104
}
105

106
// WithConcurrentStreams will enable concurrent reads and writes on the streams.
107
// Default: Disabled, meaning only one stream will be read/written at the time.
108
// Ignored if not used on a stream input.
109
func WithConcurrentStreams(enabled bool) Option {
110
	return func(o *options) {
111
		o.concReads, o.concWrites = enabled, enabled
112
	}
113
}
114

115
// WithConcurrentStreamReads will enable concurrent reads from the input streams.
116
// Default: Disabled, meaning only one stream will be read at the time.
117
// Ignored if not used on a stream input.
118
func WithConcurrentStreamReads(enabled bool) Option {
119
	return func(o *options) {
120
		o.concReads = enabled
121
	}
122
}
123

124
// WithConcurrentStreamWrites will enable concurrent writes to the the output streams.
125
// Default: Disabled, meaning only one stream will be written at the time.
126
// Ignored if not used on a stream input.
127
func WithConcurrentStreamWrites(enabled bool) Option {
128
	return func(o *options) {
129
		o.concWrites = enabled
130
	}
131
}
132

133
// WithInversionCache allows to control the inversion cache.
134
// This will cache reconstruction matrices so they can be reused.
135
// Enabled by default, or <= 64 shards for Leopard encoding.
136
func WithInversionCache(enabled bool) Option {
137
	return func(o *options) {
138
		o.inversionCache = enabled
139
		o.forcedInversionCache = true
140
	}
141
}
142

143
// WithStreamBlockSize allows to set a custom block size per round of reads/writes.
144
// If not set, any shard size set with WithAutoGoroutines will be used.
145
// If WithAutoGoroutines is also unset, 4MB will be used.
146
// Ignored if not used on stream.
147
func WithStreamBlockSize(n int) Option {
148
	return func(o *options) {
149
		o.streamBS = n
150
	}
151
}
152

153
// WithSSSE3 allows to enable/disable SSSE3 instructions.
154
// If not set, SSSE3 will be turned on or off automatically based on CPU ID information.
155
func WithSSSE3(enabled bool) Option {
156
	return func(o *options) {
157
		o.useSSSE3 = enabled
158
	}
159
}
160

161
// WithAVX2 allows to enable/disable AVX2 instructions.
162
// If not set, AVX2 will be turned on or off automatically based on CPU ID information.
163
func WithAVX2(enabled bool) Option {
164
	return func(o *options) {
165
		o.useAVX2 = enabled
166
	}
167
}
168

169
// WithSSE2 allows to enable/disable SSE2 instructions.
170
// If not set, SSE2 will be turned on or off automatically based on CPU ID information.
171
func WithSSE2(enabled bool) Option {
172
	return func(o *options) {
173
		o.useSSE2 = enabled
174
	}
175
}
176

177
// WithAVX512 allows to enable/disable AVX512 (and GFNI) instructions.
178
func WithAVX512(enabled bool) Option {
179
	return func(o *options) {
180
		o.useAVX512 = enabled
181
		o.useGFNI = enabled
182
	}
183
}
184

185
// WithGFNI allows to enable/disable AVX512+GFNI instructions.
186
// If not set, GFNI will be turned on or off automatically based on CPU ID information.
187
func WithGFNI(enabled bool) Option {
188
	return func(o *options) {
189
		o.useGFNI = enabled
190
	}
191
}
192

193
// WithJerasureMatrix causes the encoder to build the Reed-Solomon-Vandermonde
194
// matrix in the same way as done by the Jerasure library.
195
// The first row and column of the coding matrix only contains 1's in this method
196
// so the first parity chunk is always equal to XOR of all data chunks.
197
func WithJerasureMatrix() Option {
198
	return func(o *options) {
199
		o.useJerasureMatrix = true
200
		o.usePAR1Matrix = false
201
		o.useCauchy = false
202
	}
203
}
204

205
// WithPAR1Matrix causes the encoder to build the matrix how PARv1
206
// does. Note that the method they use is buggy, and may lead to cases
207
// where recovery is impossible, even if there are enough parity
208
// shards.
209
func WithPAR1Matrix() Option {
210
	return func(o *options) {
211
		o.useJerasureMatrix = false
212
		o.usePAR1Matrix = true
213
		o.useCauchy = false
214
	}
215
}
216

217
// WithCauchyMatrix will make the encoder build a Cauchy style matrix.
218
// The output of this is not compatible with the standard output.
219
// A Cauchy matrix is faster to generate. This does not affect data throughput,
220
// but will result in slightly faster start-up time.
221
func WithCauchyMatrix() Option {
222
	return func(o *options) {
223
		o.useJerasureMatrix = false
224
		o.usePAR1Matrix = false
225
		o.useCauchy = true
226
	}
227
}
228

229
// WithFastOneParityMatrix will switch the matrix to a simple xor
230
// if there is only one parity shard.
231
// The PAR1 matrix already has this property so it has little effect there.
232
func WithFastOneParityMatrix() Option {
233
	return func(o *options) {
234
		o.fastOneParity = true
235
	}
236
}
237

238
// WithCustomMatrix causes the encoder to use the manually specified matrix.
239
// customMatrix represents only the parity chunks.
240
// customMatrix must have at least ParityShards rows and DataShards columns.
241
// It can be used for interoperability with libraries which generate
242
// the matrix differently or to implement more complex coding schemes like LRC
243
// (locally reconstructible codes).
244
func WithCustomMatrix(customMatrix [][]byte) Option {
245
	return func(o *options) {
246
		o.customMatrix = customMatrix
247
	}
248
}
249

250
// WithLeopardGF16 will always use leopard GF16 for encoding,
251
// even when there is less than 256 shards.
252
// This will likely improve reconstruction time for some setups.
253
// This is not compatible with Leopard output for <= 256 shards.
254
// Note that Leopard places certain restrictions on use see other documentation.
255
func WithLeopardGF16(enabled bool) Option {
256
	return func(o *options) {
257
		if enabled {
258
			o.withLeopard = leopardGF16
259
		} else {
260
			o.withLeopard = leopardAsNeeded
261
		}
262
	}
263
}
264

265
// WithLeopardGF will use leopard GF for encoding, even when there are fewer than
266
// 256 shards.
267
// This will likely improve reconstruction time for some setups.
268
// Note that Leopard places certain restrictions on use see other documentation.
269
func WithLeopardGF(enabled bool) Option {
270
	return func(o *options) {
271
		if enabled {
272
			o.withLeopard = leopardAlways
273
		} else {
274
			o.withLeopard = leopardAsNeeded
275
		}
276
	}
277
}
278

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.