Skip to content

Commit

Permalink
Cipher 1.9x speedup (#198)
Browse files Browse the repository at this point in the history
* Cipher 1.9x speedup

Simplify cipher loop and unroll once.

```
λ benchcmp before.txt after.txt | grep -v "naive"
benchmark                                          old ns/op     new ns/op     delta
BenchmarkCipher/bytes=7;offset=1-32                7.17          7.79          +8.65%
BenchmarkCipher/bytes=125;offset=0-32              24.5          23.1          -6.07%
BenchmarkCipher/bytes=1024;offset=0-32             126           63.4          -49.87%
BenchmarkCipher/bytes=4096;offset=0-32             462           244           -47.26%
BenchmarkCipher/bytes=4100;offset=4-32             460           249           -45.93%
BenchmarkCipher/bytes=4099;offset=3-32             463           250           -45.93%
BenchmarkCipher/bytes=32775;offset=49-32           3619          1936          -46.50%

benchmark                                          old MB/s     new MB/s     speedup
BenchmarkCipher/bytes=7;offset=1-32                976.74       898.93       0.92x
BenchmarkCipher/bytes=125;offset=0-32              5092.84      5423.57      1.06x
BenchmarkCipher/bytes=1024;offset=0-32             8103.00      16159.29     1.99x
BenchmarkCipher/bytes=4096;offset=0-32             8870.86      16818.08     1.90x
BenchmarkCipher/bytes=4100;offset=4-32             8917.63      16491.32     1.85x
BenchmarkCipher/bytes=4099;offset=3-32             8854.38      16379.58     1.85x
BenchmarkCipher/bytes=32775;offset=49-32           9056.37      16926.83     1.87x
```

I tried a few variations, but this seemed fine without too many changes.

* Upgrade CI to more modern Go versions.

* Fix doc

* Revert "Upgrade CI to more modern Go versions."

This reverts commit ed29455.
  • Loading branch information
klauspost authored May 3, 2024
1 parent 02bca95 commit af7917f
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 9 deletions.
18 changes: 9 additions & 9 deletions cipher.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ func Cipher(payload []byte, mask [4]byte, offset int) {
// Count number of bytes will processed one by one from the beginning of payload.
ln := remain[mpos]
// Count number of bytes will processed one by one from the end of payload.
// This is done to process payload by 8 bytes in each iteration of main loop.
rn := (n - ln) % 8
// This is done to process payload by 16 bytes in each iteration of main loop.
rn := (n - ln) % 16

for i := 0; i < ln; i++ {
payload[i] ^= mask[(mpos+i)%4]
Expand All @@ -44,15 +44,15 @@ func Cipher(payload []byte, mask [4]byte, offset int) {
)
// Skip already processed right part.
// Get number of uint64 parts remaining to process.
n = (n - ln - rn) >> 3
n = (n - ln - rn) >> 4
j := ln
for i := 0; i < n; i++ {
var (
j = ln + (i << 3)
chunk = payload[j : j+8]
)
p := binary.LittleEndian.Uint64(chunk)
p = p ^ m2
chunk := payload[j : j+16]
p := binary.LittleEndian.Uint64(chunk) ^ m2
p2 := binary.LittleEndian.Uint64(chunk[8:]) ^ m2
binary.LittleEndian.PutUint64(chunk, p)
binary.LittleEndian.PutUint64(chunk[8:], p2)
j += 16
}
}

Expand Down
4 changes: 4 additions & 0 deletions cipher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ func BenchmarkCipher(b *testing.B) {

b.Run(fmt.Sprintf("naive_bytes=%d;offset=%d", bench.size, bench.offset), func(b *testing.B) {
var sink int64
b.SetBytes(int64(bench.size))
b.ResetTimer()
for i := 0; i < b.N; i++ {
r := cipherNaiveNoCp(bts, mask, bench.offset)
sink += int64(len(r))
Expand All @@ -177,6 +179,8 @@ func BenchmarkCipher(b *testing.B) {
})
b.Run(fmt.Sprintf("bytes=%d;offset=%d", bench.size, bench.offset), func(b *testing.B) {
var sink int64
b.SetBytes(int64(bench.size))
b.ResetTimer()
for i := 0; i < b.N; i++ {
Cipher(bts, mask, bench.offset)
sink += int64(len(bts))
Expand Down

0 comments on commit af7917f

Please sign in to comment.