Skip to content

Commit

Permalink
Unroll pure go xor loop (#172)
Browse files Browse the repository at this point in the history
* Unroll pure go xor loop

Testing with `go test -bench=x1x -tags=noasm -short`

```
before:
BenchmarkEncode2x1x1M-32           13658             87980 ns/op        35754.96 MB/s

after:
BenchmarkEncode2x1x1M-32           21633             55498 ns/op        56682.24 MB/s
```
  • Loading branch information
klauspost authored Dec 2, 2021
1 parent 62053e3 commit 5593e2b
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 7 deletions.
2 changes: 1 addition & 1 deletion galois_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func galMulSliceXor(c byte, in, out []byte, o *options) {
}
}

// slice galois add
// simple slice xor
func sliceXor(in, out []byte, o *options) {
if o.useSSE2 {
if len(in) >= bigSwitchover {
Expand Down
2 changes: 1 addition & 1 deletion galois_arm64.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func galMulSliceXor(c byte, in, out []byte, o *options) {
}
}

// slice galois add
// simple slice xor
func sliceXor(in, out []byte, o *options) {

galXorNEON(in, out)
Expand Down
23 changes: 18 additions & 5 deletions galois_noasm.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

package reedsolomon

import "encoding/binary"

func galMulSlice(c byte, in, out []byte, o *options) {
out = out[:len(in)]
if c == 1 {
Expand All @@ -22,9 +24,7 @@ func galMulSlice(c byte, in, out []byte, o *options) {
func galMulSliceXor(c byte, in, out []byte, o *options) {
out = out[:len(in)]
if c == 1 {
for n, input := range in {
out[n] ^= input
}
sliceXor(in, out, o)
return
}
mt := mulTable[c][:256]
Expand All @@ -33,8 +33,21 @@ func galMulSliceXor(c byte, in, out []byte, o *options) {
}
}

// slice galois add
func sliceXor(in, out []byte, o *options) {
// simple slice xor
func sliceXor(in, out []byte, _ *options) {
for len(out) >= 32 {
inS := in[:32]
v0 := binary.LittleEndian.Uint64(out[:]) ^ binary.LittleEndian.Uint64(inS[:])
v1 := binary.LittleEndian.Uint64(out[8:]) ^ binary.LittleEndian.Uint64(inS[8:])
v2 := binary.LittleEndian.Uint64(out[16:]) ^ binary.LittleEndian.Uint64(inS[16:])
v3 := binary.LittleEndian.Uint64(out[24:]) ^ binary.LittleEndian.Uint64(inS[24:])
binary.LittleEndian.PutUint64(out[:], v0)
binary.LittleEndian.PutUint64(out[8:], v1)
binary.LittleEndian.PutUint64(out[16:], v2)
binary.LittleEndian.PutUint64(out[24:], v3)
out = out[32:]
in = in[32:]
}
for n, input := range in {
out[n] ^= input
}
Expand Down
1 change: 1 addition & 0 deletions reedsolomon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func TestMain(m *testing.M) {
}

func testOptions(o ...Option) []Option {
o = append(o, WithFastOneParityMatrix())
if *noSSSE3 {
o = append(o, withSSSE3(false))
}
Expand Down

0 comments on commit 5593e2b

Please sign in to comment.