mirror of https://github.com/bitcoin/bitcoin.git
crypto: optimize SipHash Write() method with chunked processing
Replace byte-by-byte processing in CSipHasher::Write() with an optimized chunked approach that processes data in 8-byte aligned blocks when possible. The previous implementation processed input data one byte at a time using data.front() and data.subspan(1), which resulted in significant overhead for large inputs due to repeated bounds checking and span manipulations. The new implementation: - Handles initial unaligned bytes to reach an 8-byte boundary - Processes aligned 8-byte chunks directly using memcpy for efficiency - Handles remaining bytes at the end This optimization provides substantial performance improvements across Bitcoin operations that rely on SipHash: - GCSFilterConstruct: 16% improvement - WalletIsMineDescriptors: 11.6% improvement - WalletIsMineMigratedDescriptors: 59.0% improvement These improvements are particularly beneficial for wallet operations and block filter construction. ./bin/bench_bitcoin -filter="(WalletIsMineMigratedDescriptors|WalletIsMineDescriptors|GCSFilterConstruct|AddrManSelect)" -output-csv=bench_old.csv --min-time=60000 | ns/op | op/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 214.55 | 4,660,983.40 | 0.2% | 65.89 | `AddrManSelect` | 12,983,090.72 | 77.02 | 0.1% | 66.00 | `GCSFilterConstruct` | 100.29 | 9,971,046.61 | 0.0% | 66.02 | `WalletIsMineDescriptors` | 115.42 | 8,664,379.92 | 0.0% | 66.02 | `WalletIsMineMigratedDescriptors` ./bin/bench_bitcoin -filter="(WalletIsMineMigratedDescriptors|WalletIsMineDescriptors|GCSFilterConstruct|AddrManSelect)" -output-csv=bench_new.csv --min-time=60000 | ns/op | op/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 210.60 | 4,748,271.82 | 0.1% | 65.93 | `AddrManSelect` | 11,155,751.42 | 89.64 | 0.1% | 65.99 | `GCSFilterConstruct` | 89.87 | 11,126,702.73 | 0.0% | 66.01 | `WalletIsMineDescriptors` | 72.67 | 13,761,145.85 | 0.0% | 66.01 | `WalletIsMineMigratedDescriptors`
This commit is contained in:
parent
720045094b
commit
5ba5198c45
|
@ -74,17 +74,29 @@ CSipHasher& CSipHasher::Write(std::span<const unsigned char> data)
|
|||
t = 0;
|
||||
}
|
||||
|
||||
// Process aligned 8-byte chunks directly
|
||||
while (size >= 8) {
|
||||
uint64_t chunk;
|
||||
std::memcpy(&chunk, ptr, 8);
|
||||
if constexpr (std::endian::native == std::endian::big) {
|
||||
chunk = internal_bswap_64(chunk);
|
||||
}
|
||||
|
||||
v3 ^= chunk;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= chunk;
|
||||
|
||||
ptr += 8;
|
||||
size -= 8;
|
||||
c += 8;
|
||||
}
|
||||
|
||||
//Handle remaining unaligned bytes
|
||||
while (size > 0) {
|
||||
t |= uint64_t{*ptr} << (8 * (c & 7));
|
||||
c++;
|
||||
if ((c & 7) == 0) {
|
||||
v3 ^= t;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= t;
|
||||
t = 0;
|
||||
}
|
||||
ptr++;
|
||||
c++;
|
||||
size--;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue