options.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package reedsolomon
  2. import (
  3. "runtime"
  4. "github.com/klauspost/cpuid"
  5. )
  6. // Option allows to override processing parameters.
  7. type Option func(*options)
  8. type options struct {
  9. maxGoroutines int
  10. minSplitSize int
  11. useAVX512, useAVX2, useSSSE3, useSSE2 bool
  12. usePAR1Matrix bool
  13. useCauchy bool
  14. shardSize int
  15. }
  16. var defaultOptions = options{
  17. maxGoroutines: 384,
  18. minSplitSize: 1024,
  19. }
  20. func init() {
  21. if runtime.GOMAXPROCS(0) <= 1 {
  22. defaultOptions.maxGoroutines = 1
  23. }
  24. // Detect CPU capabilities.
  25. defaultOptions.useSSSE3 = cpuid.CPU.SSSE3()
  26. defaultOptions.useSSE2 = cpuid.CPU.SSE2()
  27. defaultOptions.useAVX2 = cpuid.CPU.AVX2()
  28. defaultOptions.useAVX512 = cpuid.CPU.AVX512F() && cpuid.CPU.AVX512BW() && amd64
  29. }
  30. // WithMaxGoroutines is the maximum number of goroutines number for encoding & decoding.
  31. // Jobs will be split into this many parts, unless each goroutine would have to process
  32. // less than minSplitSize bytes (set with WithMinSplitSize).
  33. // For the best speed, keep this well above the GOMAXPROCS number for more fine grained
  34. // scheduling.
  35. // If n <= 0, it is ignored.
  36. func WithMaxGoroutines(n int) Option {
  37. return func(o *options) {
  38. if n > 0 {
  39. o.maxGoroutines = n
  40. }
  41. }
  42. }
  43. // WithAutoGoroutines will adjust the number of goroutines for optimal speed with a
  44. // specific shard size.
  45. // Send in the shard size you expect to send. Other shard sizes will work, but may not
  46. // run at the optimal speed.
  47. // Overwrites WithMaxGoroutines.
  48. // If shardSize <= 0, it is ignored.
  49. func WithAutoGoroutines(shardSize int) Option {
  50. return func(o *options) {
  51. o.shardSize = shardSize
  52. }
  53. }
  54. // WithMinSplitSize is the minimum encoding size in bytes per goroutine.
  55. // See WithMaxGoroutines on how jobs are split.
  56. // If n <= 0, it is ignored.
  57. func WithMinSplitSize(n int) Option {
  58. return func(o *options) {
  59. if n > 0 {
  60. o.minSplitSize = n
  61. }
  62. }
  63. }
  64. func withSSE3(enabled bool) Option {
  65. return func(o *options) {
  66. o.useSSSE3 = enabled
  67. }
  68. }
  69. func withAVX2(enabled bool) Option {
  70. return func(o *options) {
  71. o.useAVX2 = enabled
  72. }
  73. }
  74. func withSSE2(enabled bool) Option {
  75. return func(o *options) {
  76. o.useSSE2 = enabled
  77. }
  78. }
  79. func withAVX512(enabled bool) Option {
  80. return func(o *options) {
  81. o.useAVX512 = enabled
  82. }
  83. }
  84. // WithPAR1Matrix causes the encoder to build the matrix how PARv1
  85. // does. Note that the method they use is buggy, and may lead to cases
  86. // where recovery is impossible, even if there are enough parity
  87. // shards.
  88. func WithPAR1Matrix() Option {
  89. return func(o *options) {
  90. o.usePAR1Matrix = true
  91. o.useCauchy = false
  92. }
  93. }
  94. // WithCauchyMatrix will make the encoder build a Cauchy style matrix.
  95. // The output of this is not compatible with the standard output.
  96. // A Cauchy matrix is faster to generate. This does not affect data throughput,
  97. // but will result in slightly faster start-up time.
  98. func WithCauchyMatrix() Option {
  99. return func(o *options) {
  100. o.useCauchy = true
  101. o.usePAR1Matrix = false
  102. }
  103. }