uses rust intrinsics to convert hashes to u64 (#12097)

This commit is contained in:
behzad nouri 2020-09-09 15:28:17 +00:00 committed by GitHub
parent 697e004e0d
commit 28f2fa3fd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 6 deletions

View File

@ -94,6 +94,9 @@ name = "banking_stage"
[[bench]]
name = "blockstore"
[[bench]]
name = "crds_gossip_pull"
[[bench]]
name = "gen_keys"

View File

@ -0,0 +1,26 @@
#![feature(test)]
extern crate test;
use rand::{thread_rng, Rng};
use solana_core::crds_gossip_pull::CrdsFilter;
use solana_sdk::hash::{Hash, HASH_BYTES};
use test::Bencher;
#[bench]
fn bench_hash_as_u64(bencher: &mut Bencher) {
let mut rng = thread_rng();
let hashes: Vec<_> = (0..1000)
.map(|_| {
let mut buf = [0u8; HASH_BYTES];
rng.fill(&mut buf);
Hash::new(&buf)
})
.collect();
bencher.iter(|| {
hashes
.iter()
.map(CrdsFilter::hash_as_u64)
.collect::<Vec<_>>()
});
}

View File

@ -22,6 +22,7 @@ use solana_sdk::pubkey::Pubkey;
use std::cmp;
use std::collections::VecDeque;
use std::collections::{HashMap, HashSet};
use std::convert::TryInto;
pub const CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS: u64 = 15000;
// The maximum age of a value received over pull responses
@ -74,12 +75,8 @@ impl CrdsFilter {
((num_items / max_items).log2().ceil()).max(0.0) as u32
}
pub fn hash_as_u64(item: &Hash) -> u64 {
let arr = item.as_ref();
let mut accum = 0;
for (i, val) in arr.iter().enumerate().take(8) {
accum |= (u64::from(*val)) << (i * 8) as u64;
}
accum
let buf = item.as_ref()[..8].try_into().unwrap();
u64::from_le_bytes(buf)
}
pub fn test_mask_u64(&self, item: u64, ones: u64) -> bool {
let bits = item | ones;
@ -543,6 +540,31 @@ mod test {
use solana_sdk::hash::{hash, HASH_BYTES};
use solana_sdk::packet::PACKET_DATA_SIZE;
#[test]
fn test_hash_as_u64() {
let arr: Vec<u8> = (0..HASH_BYTES).map(|i| i as u8 + 1).collect();
let hash = Hash::new(&arr);
assert_eq!(CrdsFilter::hash_as_u64(&hash), 0x807060504030201);
}
#[test]
fn test_hash_as_u64_random() {
fn hash_as_u64_bitops(hash: &Hash) -> u64 {
let mut out = 0;
for (i, val) in hash.as_ref().iter().enumerate().take(8) {
out |= (u64::from(*val)) << (i * 8) as u64;
}
out
}
let mut rng = thread_rng();
for _ in 0..100 {
let mut buf = [0u8; HASH_BYTES];
rng.fill(&mut buf);
let hash = Hash::new(&buf);
assert_eq!(CrdsFilter::hash_as_u64(&hash), hash_as_u64_bitops(&hash));
}
}
#[test]
fn test_new_pull_with_stakes() {
let mut crds = Crds::default();