Skip to content

Commit

Permalink
Unroll one more loop
Browse files Browse the repository at this point in the history
I also tried unrolling the 256-iteration loop further below, but it actually caused a
slowdown (my guess is either branch prediction stopped kicking in or the instruction
cache was being maculated).
  • Loading branch information
Vurich committed Jul 19, 2017
1 parent d51958d commit 2cc1c92
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 16 additions & 9 deletions ethash/src/compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)

let index = fnv_hash(
f_mix.get_unchecked(0).as_words().get_unchecked(0) ^ i,
*mix.get_unchecked(0).as_words().get_unchecked(i_usize % MIX_WORDS)
*mix.get_unchecked(0).as_words().get_unchecked(i as usize % MIX_WORDS)
) % num_full_pages;

unroll! {
Expand All @@ -324,14 +324,18 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
}
}

debug_assert_eq!(MIX_WORDS / 4, 8);

// compress mix
for i in 0..(MIX_WORDS / 4) {
let w = i * 4;
let mut reduction = *mix.get_unchecked(0).as_words().get_unchecked(w + 0);
reduction = reduction.wrapping_mul(FNV_PRIME) ^ *mix.get_unchecked(0).as_words().get_unchecked(w + 1);
reduction = reduction.wrapping_mul(FNV_PRIME) ^ *mix.get_unchecked(0).as_words().get_unchecked(w + 2);
reduction = reduction.wrapping_mul(FNV_PRIME) ^ *mix.get_unchecked(0).as_words().get_unchecked(w + 3);
*mix.get_unchecked_mut(0).as_words_mut().get_unchecked_mut(i) = reduction;
unroll! {
for i in 0..8 {
let w = i * 4;
let mut reduction = *mix.get_unchecked(0).as_words().get_unchecked(w + 0);
reduction = reduction.wrapping_mul(FNV_PRIME) ^ *mix.get_unchecked(0).as_words().get_unchecked(w + 1);
reduction = reduction.wrapping_mul(FNV_PRIME) ^ *mix.get_unchecked(0).as_words().get_unchecked(w + 2);
reduction = reduction.wrapping_mul(FNV_PRIME) ^ *mix.get_unchecked(0).as_words().get_unchecked(w + 3);
*mix.get_unchecked_mut(0).as_words_mut().get_unchecked_mut(i) = reduction;
}
}

let mut mix_hash = [0u8; 32];
Expand All @@ -356,13 +360,15 @@ fn calculate_dag_item(node_index: u32, cache: &[Node]) -> Node {
*ret.as_words_mut().get_unchecked_mut(0) ^= node_index;
sha3::sha3_512(ret.bytes.as_mut_ptr(), ret.bytes.len(), ret.bytes.as_ptr(), ret.bytes.len());

for i in 0..ETHASH_DATASET_PARENTS {
for i_usize in 0..ETHASH_DATASET_PARENTS {
let i = i_usize as u32;
let parent_index = fnv_hash(node_index ^ i, *ret.as_words().get_unchecked(i as usize % NODE_WORDS)) % num_parent_nodes as u32;
let parent = cache.get_unchecked(parent_index as usize);
for w in 0..NODE_WORDS {
*ret.as_words_mut().get_unchecked_mut(w) = fnv_hash(*ret.as_words().get_unchecked(w), *parent.as_words().get_unchecked(w));
}
}

sha3::sha3_512(ret.bytes.as_mut_ptr(), ret.bytes.len(), ret.bytes.as_ptr(), ret.bytes.len());
ret
}
Expand All @@ -386,6 +392,7 @@ fn light_new(block_number: u64) -> Light {
sha3::sha3_512(nodes.get_unchecked_mut(i).bytes.as_mut_ptr(), NODE_BYTES, nodes.get_unchecked(i - 1).bytes.as_ptr(), NODE_BYTES);
}

// This _should_ get unrolled by the compiler, since it's not using the loop variable.
for _ in 0..ETHASH_CACHE_ROUNDS {
for i in 0..num_nodes {
let idx = *nodes.get_unchecked_mut(i).as_words().get_unchecked(0) as usize % num_nodes;
Expand Down

0 comments on commit 2cc1c92

Please sign in to comment.