options.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. 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.useAVX2 = cpuid.CPU.AVX2()
  27. defaultOptions.useSSE2 = cpuid.CPU.SSE2()
  28. }
  29. // WithMaxGoroutines is the maximum number of goroutines number for encoding & decoding.
  30. // Jobs will be split into this many parts, unless each goroutine would have to process
  31. // less than minSplitSize bytes (set with WithMinSplitSize).
  32. // For the best speed, keep this well above the GOMAXPROCS number for more fine grained
  33. // scheduling.
  34. // If n <= 0, it is ignored.
  35. func WithMaxGoroutines(n int) Option {
  36. return func(o *options) {
  37. if n > 0 {
  38. o.maxGoroutines = n
  39. }
  40. }
  41. }
  42. // WithAutoGoroutines will adjust the number of goroutines for optimal speed with a
  43. // specific shard size.
  44. // Send in the shard size you expect to send. Other shard sizes will work, but may not
  45. // run at the optimal speed.
  46. // Overwrites WithMaxGoroutines.
  47. // If shardSize <= 0, it is ignored.
  48. func WithAutoGoroutines(shardSize int) Option {
  49. return func(o *options) {
  50. o.shardSize = shardSize
  51. }
  52. }
  53. // WithMinSplitSize is the minimum encoding size in bytes per goroutine.
  54. // See WithMaxGoroutines on how jobs are split.
  55. // If n <= 0, it is ignored.
  56. func WithMinSplitSize(n int) Option {
  57. return func(o *options) {
  58. if n > 0 {
  59. o.minSplitSize = n
  60. }
  61. }
  62. }
  63. func withSSE3(enabled bool) Option {
  64. return func(o *options) {
  65. o.useSSSE3 = enabled
  66. }
  67. }
  68. func withAVX2(enabled bool) Option {
  69. return func(o *options) {
  70. o.useAVX2 = enabled
  71. }
  72. }
  73. func withSSE2(enabled bool) Option {
  74. return func(o *options) {
  75. o.useSSE2 = enabled
  76. }
  77. }
  78. // WithPAR1Matrix causes the encoder to build the matrix how PARv1
  79. // does. Note that the method they use is buggy, and may lead to cases
  80. // where recovery is impossible, even if there are enough parity
  81. // shards.
  82. func WithPAR1Matrix() Option {
  83. return func(o *options) {
  84. o.usePAR1Matrix = true
  85. o.useCauchy = false
  86. }
  87. }
  88. // WithCauchyMatrix will make the encoder build a Cauchy style matrix.
  89. // The output of this is not compatible with the standard output.
  90. // A Cauchy matrix is faster to generate. This does not affect data throughput,
  91. // but will result in slightly faster start-up time.
  92. func WithCauchyMatrix() Option {
  93. return func(o *options) {
  94. o.useCauchy = true
  95. o.usePAR1Matrix = false
  96. }
  97. }