Skip to content

Commit af7917f

Browse files
authored
Cipher 1.9x speedup (#198)
* 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.
1 parent 02bca95 commit af7917f

File tree

2 files changed

+13
-9
lines changed

2 files changed

+13
-9
lines changed

cipher.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ func Cipher(payload []byte, mask [4]byte, offset int) {
2525
// Count number of bytes will processed one by one from the beginning of payload.
2626
ln := remain[mpos]
2727
// Count number of bytes will processed one by one from the end of payload.
28-
// This is done to process payload by 8 bytes in each iteration of main loop.
29-
rn := (n - ln) % 8
28+
// This is done to process payload by 16 bytes in each iteration of main loop.
29+
rn := (n - ln) % 16
3030

3131
for i := 0; i < ln; i++ {
3232
payload[i] ^= mask[(mpos+i)%4]
@@ -44,15 +44,15 @@ func Cipher(payload []byte, mask [4]byte, offset int) {
4444
)
4545
// Skip already processed right part.
4646
// Get number of uint64 parts remaining to process.
47-
n = (n - ln - rn) >> 3
47+
n = (n - ln - rn) >> 4
48+
j := ln
4849
for i := 0; i < n; i++ {
49-
var (
50-
j = ln + (i << 3)
51-
chunk = payload[j : j+8]
52-
)
53-
p := binary.LittleEndian.Uint64(chunk)
54-
p = p ^ m2
50+
chunk := payload[j : j+16]
51+
p := binary.LittleEndian.Uint64(chunk) ^ m2
52+
p2 := binary.LittleEndian.Uint64(chunk[8:]) ^ m2
5553
binary.LittleEndian.PutUint64(chunk, p)
54+
binary.LittleEndian.PutUint64(chunk[8:], p2)
55+
j += 16
5656
}
5757
}
5858

cipher_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ func BenchmarkCipher(b *testing.B) {
169169

170170
b.Run(fmt.Sprintf("naive_bytes=%d;offset=%d", bench.size, bench.offset), func(b *testing.B) {
171171
var sink int64
172+
b.SetBytes(int64(bench.size))
173+
b.ResetTimer()
172174
for i := 0; i < b.N; i++ {
173175
r := cipherNaiveNoCp(bts, mask, bench.offset)
174176
sink += int64(len(r))
@@ -177,6 +179,8 @@ func BenchmarkCipher(b *testing.B) {
177179
})
178180
b.Run(fmt.Sprintf("bytes=%d;offset=%d", bench.size, bench.offset), func(b *testing.B) {
179181
var sink int64
182+
b.SetBytes(int64(bench.size))
183+
b.ResetTimer()
180184
for i := 0; i < b.N; i++ {
181185
Cipher(bts, mask, bench.offset)
182186
sink += int64(len(bts))

0 commit comments

Comments
 (0)