[ethash] remove manual unrolling (#11069)
* [ethash] remove unroll in calculate_dag_item * [ethash] add keccak bench * [ethash] remove unroll! completely * [ethash] specify required-features for benches * [ethcore/verification] specify required-features for benches * [CI] simplify cargo-check-benches step
This commit is contained in:
parent
2627288311
commit
fc22c58408
@ -100,9 +100,7 @@ cargo-check-benches:
|
||||
stage: test
|
||||
<<: *docker-cache-status
|
||||
script:
|
||||
- time (cargo check --all --benches --exclude ethash --exclude verification --target $CARGO_TARGET --locked --verbose --color=always)
|
||||
- time (cd ethash; cargo check --benches --features bench --target $CARGO_TARGET --locked --verbose --color=always)
|
||||
- time (cd ethcore/verification; cargo check --benches --features bench --target $CARGO_TARGET --locked --verbose --color=always)
|
||||
- time cargo check --all --benches --target $CARGO_TARGET --locked --verbose --color=always
|
||||
- sccache -s
|
||||
|
||||
cargo-audit:
|
||||
|
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -936,7 +936,6 @@ version = "1.12.0"
|
||||
dependencies = [
|
||||
"common-types 0.1.0",
|
||||
"criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -6,7 +6,6 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
common-types = { path = "../ethcore/types" }
|
||||
crunchy = "0.1.0"
|
||||
either = "1.0.0"
|
||||
ethereum-types = "0.6.0"
|
||||
keccak-hash = "0.2.0"
|
||||
@ -29,7 +28,9 @@ bench = []
|
||||
[[bench]]
|
||||
name = "basic"
|
||||
harness = false
|
||||
required-features = ['bench']
|
||||
|
||||
[[bench]]
|
||||
name = "progpow"
|
||||
harness = false
|
||||
required-features = ['bench']
|
||||
|
@ -20,7 +20,7 @@ extern crate ethash;
|
||||
extern crate common_types;
|
||||
|
||||
use criterion::Criterion;
|
||||
use ethash::NodeCacheBuilder;
|
||||
use ethash::{NodeCacheBuilder, keccak};
|
||||
use common_types::engines::OptimizeFor;
|
||||
|
||||
const HASH: [u8; 32] = [
|
||||
@ -40,7 +40,8 @@ const NONCE: u64 = 0xd7b3ac70a301a249;
|
||||
criterion_group! {
|
||||
name = basic;
|
||||
config = dont_take_an_eternity_to_run();
|
||||
targets = bench_light_compute_memmap,
|
||||
targets = bench_keccak_512_inplace,
|
||||
bench_light_compute_memmap,
|
||||
bench_light_compute_memory,
|
||||
bench_light_new_round_trip_memmap,
|
||||
bench_light_new_round_trip_memory,
|
||||
@ -56,6 +57,13 @@ fn dont_take_an_eternity_to_run() -> Criterion {
|
||||
.sample_size(10)
|
||||
}
|
||||
|
||||
fn bench_keccak_512_inplace(b: &mut Criterion) {
|
||||
b.bench_function("bench_keccak_512_inplace", move |b| b.iter(|| {
|
||||
let mut data = [4u8; 64];
|
||||
keccak::keccak_512::inplace(&mut data);
|
||||
}));
|
||||
}
|
||||
|
||||
fn bench_light_compute_memmap(b: &mut Criterion) {
|
||||
use std::env;
|
||||
|
||||
|
@ -21,7 +21,7 @@ use memmap::MmapMut;
|
||||
use parking_lot::Mutex;
|
||||
use seed_compute::SeedHashCompute;
|
||||
|
||||
use shared::{ETHASH_CACHE_ROUNDS, NODE_BYTES, NODE_DWORDS, Node, epoch, get_cache_size, to_hex};
|
||||
use shared::{ETHASH_CACHE_ROUNDS, NODE_BYTES, Node, epoch, get_cache_size, to_hex};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fs;
|
||||
@ -317,11 +317,6 @@ unsafe fn initialize_memory(memory: *mut Node, num_nodes: usize, ident: &H256) {
|
||||
// Now this is initialized, we can treat it as a slice.
|
||||
let nodes: &mut [Node] = slice::from_raw_parts_mut(memory, num_nodes);
|
||||
|
||||
// For `unroll!`, see below. If the literal in `unroll!` is not the same as the RHS here then
|
||||
// these have got out of sync! Don't let this happen!
|
||||
debug_assert_eq!(NODE_DWORDS, 8);
|
||||
|
||||
// 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 data_idx = (num_nodes - 1 + i) % num_nodes;
|
||||
@ -331,11 +326,8 @@ unsafe fn initialize_memory(memory: *mut Node, num_nodes: usize, ident: &H256) {
|
||||
let mut data: Node = nodes.get_unchecked(data_idx).clone();
|
||||
let rhs: &Node = nodes.get_unchecked(idx);
|
||||
|
||||
unroll! {
|
||||
for w in 0..8 {
|
||||
*data.as_dwords_mut().get_unchecked_mut(w) ^=
|
||||
*rhs.as_dwords().get_unchecked(w);
|
||||
}
|
||||
for (a, b) in data.as_dwords_mut().iter_mut().zip(rhs.as_dwords()) {
|
||||
*a ^= *b;
|
||||
}
|
||||
|
||||
data
|
||||
|
@ -239,7 +239,6 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
|
||||
fnv_hash(first_val ^ i, mix_words[i as usize % MIX_WORDS]) % num_full_pages
|
||||
};
|
||||
|
||||
unroll! {
|
||||
// MIX_NODES
|
||||
for n in 0..2 {
|
||||
let tmp_node = calculate_dag_item(
|
||||
@ -247,16 +246,9 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
|
||||
cache,
|
||||
);
|
||||
|
||||
unroll! {
|
||||
// NODE_WORDS
|
||||
for w in 0..16 {
|
||||
mix[n].as_words_mut()[w] =
|
||||
fnv_hash(
|
||||
mix[n].as_words()[w],
|
||||
tmp_node.as_words()[w],
|
||||
);
|
||||
}
|
||||
}
|
||||
for (a, b) in mix[n].as_words_mut().iter_mut().zip(tmp_node.as_words()) {
|
||||
*a = fnv_hash(*a, *b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -277,7 +269,6 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
|
||||
|
||||
// Compress mix
|
||||
debug_assert_eq!(MIX_WORDS / 4, 8);
|
||||
unroll! {
|
||||
for i in 0..8 {
|
||||
let w = i * 4;
|
||||
|
||||
@ -288,7 +279,6 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
|
||||
compress[i] = reduction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mix_hash = buf.compress_bytes;
|
||||
|
||||
@ -312,7 +302,6 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
|
||||
ProofOfWork { mix_hash: mix_hash, value: value }
|
||||
}
|
||||
|
||||
// TODO: Use the `simd` crate
|
||||
pub fn calculate_dag_item(node_index: u32, cache: &[Node]) -> Node {
|
||||
let num_parent_nodes = cache.len();
|
||||
let mut ret = cache[node_index as usize % num_parent_nodes].clone();
|
||||
@ -326,10 +315,8 @@ pub fn calculate_dag_item(node_index: u32, cache: &[Node]) -> Node {
|
||||
num_parent_nodes as u32;
|
||||
let parent = &cache[parent_index as usize];
|
||||
|
||||
unroll! {
|
||||
for w in 0..16 {
|
||||
ret.as_words_mut()[w] = fnv_hash(ret.as_words()[w], parent.as_words()[w]);
|
||||
}
|
||||
for (a, b) in ret.as_words_mut().iter_mut().zip(parent.as_words()) {
|
||||
*a = fnv_hash(*a, *b);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,8 +21,6 @@ extern crate memmap;
|
||||
extern crate parking_lot;
|
||||
extern crate primal;
|
||||
|
||||
#[macro_use]
|
||||
extern crate crunchy;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
@ -44,6 +42,9 @@ mod compute;
|
||||
|
||||
mod seed_compute;
|
||||
mod cache;
|
||||
#[cfg(feature = "bench")]
|
||||
pub mod keccak;
|
||||
#[cfg(not(feature = "bench"))]
|
||||
mod keccak;
|
||||
mod shared;
|
||||
|
||||
|
@ -9,6 +9,7 @@ license = "GPL-3.0"
|
||||
[[bench]]
|
||||
name = "verification"
|
||||
harness = false
|
||||
required-features = ['bench']
|
||||
|
||||
[dependencies]
|
||||
blockchain = { package = "ethcore-blockchain", path = "../blockchain" }
|
||||
|
Loading…
Reference in New Issue
Block a user