mirror of
https://github.com/status-im/nim-ethash.git
synced 2025-02-21 08:18:12 +00:00
Add benchmark (mkcache not compiling yet)
This commit is contained in:
parent
f6f2725cf2
commit
7669f820dc
26
benchmarks/benchmark.nim
Normal file
26
benchmarks/benchmark.nim
Normal file
@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2018 Status Research & Development GmbH
|
||||
# Distributed under the Apache v2 License (license terms are at http://www.apache.org/licenses/LICENSE-2.0).
|
||||
|
||||
import ../src/ethash, times
|
||||
|
||||
|
||||
let
|
||||
seed = hexToSeqBytesBE("9410b944535a83d9adf6bbdcc80e051f30676173c16ca0d32d6f1263fc246466")
|
||||
previous_hash = hexToSeqBytesBE("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
|
||||
|
||||
|
||||
var start = cpuTime() # Note for a multithreaded program, it adds the time taken on each Cpu
|
||||
|
||||
|
||||
# params.full_size = 262147 * 4096; // 1GBish;
|
||||
# params.full_size = 32771 * 4096; // 128MBish;
|
||||
# params.full_size = 8209 * 4096; // 8MBish;
|
||||
# params.cache_size = 8209*4096;
|
||||
# params.cache_size = 2053*4096;
|
||||
|
||||
# Default:
|
||||
# Dataset 2^30
|
||||
# Cache 2^24
|
||||
|
||||
let cache = mkcache(8209*4096, seed)
|
||||
echo cpuTime() - start
|
@ -6,6 +6,7 @@ import math, sequtils,
|
||||
keccak_tiny
|
||||
|
||||
import ./private/[primes, casting, functional]
|
||||
export toHex, hexToSeqBytesBE
|
||||
|
||||
# TODO: Switching from default int to uint64
|
||||
# Note: array/seq indexing requires an Ordinal, uint64 are not.
|
||||
@ -50,7 +51,7 @@ proc get_full_size(block_number: Natural): int {.noSideEffect.}=
|
||||
# ###############################################################################
|
||||
# Cache generation
|
||||
|
||||
proc mkcache(cache_size, seed: int): seq[Hash[512]] {.noSideEffect.}=
|
||||
proc mkcache*(cache_size: int, seed: seq[byte]): seq[Hash[512]] {.noSideEffect.}=
|
||||
|
||||
# The starting cache size is a set of 524288 64-byte values
|
||||
|
||||
@ -58,7 +59,7 @@ proc mkcache(cache_size, seed: int): seq[Hash[512]] {.noSideEffect.}=
|
||||
|
||||
# Sequentially produce the initial dataset
|
||||
result = newSeq[Hash[512]](n)
|
||||
result[0] = sha3_512 seed.toU512 # TODO: spec is unclear how to hash i64/u64 integers
|
||||
result[0] = sha3_512 seed
|
||||
|
||||
for i in 1 ..< n:
|
||||
result[i] = sha3_512 result[i-1].toU512
|
||||
@ -112,12 +113,18 @@ proc calc_dataset_item(cache: seq[Hash[512]], i: Natural): Hash[512] {.noSideEff
|
||||
mix[] = toU512 sha3_512 mix[]
|
||||
|
||||
# FNV with a lots of random cache nodes based on i
|
||||
# TODO: we use FNV with word size 64 bit while ethash implementation is using 32 bit words
|
||||
# tests needed
|
||||
for j in 0'u64 ..< DATASET_PARENTS:
|
||||
let cache_index = fnv(i.uint64 xor j, mix[j mod r])
|
||||
mix[] = zipMap(mix[], cache[cache_index.int mod n].toU512, fnv(x, y))
|
||||
|
||||
result = sha3_512 mix[]
|
||||
|
||||
proc calc_dataset(cache: var seq[Hash[512]]) {.noSideEffect.} =
|
||||
for i, hash in cache.mpairs:
|
||||
hash = calc_dataset_item(cache, i)
|
||||
|
||||
# ###############################################################################
|
||||
when isMainModule:
|
||||
echo get_full_size(100000)
|
||||
|
@ -24,11 +24,62 @@ proc `xor`*(x, y: U512): U512 {.inline, noSideEffect, noInit.}=
|
||||
proc toHash512*(x: U512): Hash[512] {.inline, noSideEffect, noInit.}=
|
||||
cast[type result](x)
|
||||
|
||||
# proc asByteArray*[T: not (ref|ptr|string)](data: T): array[sizeof(T), byte] =
|
||||
# ## Cast stack allocated types to an array of byte
|
||||
# cast[type result](data)
|
||||
|
||||
# proc asByteArray*(data: Hash[512]): array[64, byte] =
|
||||
# ## Workaround: Nim cannot evaluate size of arrays
|
||||
# ## https://github.com/nim-lang/Nim/issues/5802
|
||||
# cast[type result](data)
|
||||
# ### Hex conversion
|
||||
|
||||
|
||||
type ByteArrayBE*[N: static[int]] = array[N, byte]
|
||||
## A byte array that stores bytes in big-endian order
|
||||
|
||||
proc readHexChar(c: char): byte {.noSideEffect.}=
|
||||
## Converts an hex char to a byte
|
||||
case c
|
||||
of '0'..'9': result = byte(ord(c) - ord('0'))
|
||||
of 'a'..'f': result = byte(ord(c) - ord('a') + 10)
|
||||
of 'A'..'F': result = byte(ord(c) - ord('A') + 10)
|
||||
else:
|
||||
raise newException(ValueError, $c & "is not a hexademical character")
|
||||
|
||||
|
||||
proc hexToByteArrayBE*[N: static[int]](hexStr: string): ByteArrayBE[N] {.noSideEffect, noInit.}=
|
||||
## Read an hex string and store it in a Byte Array in Big-Endian order
|
||||
var i = 0
|
||||
if hexStr[i] == '0' and (hexStr[i+1] == 'x' or hexStr[i+1] == 'X'):
|
||||
inc(i, 2) # Ignore 0x and 0X prefix
|
||||
|
||||
assert hexStr.len - i == 2*N
|
||||
|
||||
while i < N:
|
||||
result[i] = hexStr[2*i].readHexChar shl 4 or hexStr[2*i+1].readHexChar
|
||||
inc(i)
|
||||
|
||||
proc hexToSeqBytesBE*(hexStr: string): seq[byte] {.noSideEffect.}=
|
||||
## Read an hex string and store it in a sequence of bytes in Big-Endian order
|
||||
var i = 0
|
||||
if hexStr[i] == '0' and (hexStr[i+1] == 'x' or hexStr[i+1] == 'X'):
|
||||
inc(i, 2) # Ignore 0x and 0X prefix
|
||||
|
||||
let N = (hexStr.len - i) div 2
|
||||
|
||||
result = newSeq[byte](N)
|
||||
while i < N:
|
||||
result[i] = hexStr[2*i].readHexChar shl 4 or hexStr[2*i+1].readHexChar
|
||||
inc(i)
|
||||
|
||||
proc toHex*(ba: seq[byte]): string {.noSideEffect, noInit.}=
|
||||
## Convert a big-endian byte-array to its hex representation
|
||||
## Output is in lowercase
|
||||
##
|
||||
## Warning ⚠: Do not use toHex for hex representation of Public Keys
|
||||
## Use the ``serialize`` proc:
|
||||
## - PublicKey is actually 2 separate numbers corresponding to coordinate on elliptic curve
|
||||
## - It is resistant against timing attack
|
||||
|
||||
let N = ba.len
|
||||
const hexChars = "0123456789abcdef"
|
||||
|
||||
result = newString(2*N)
|
||||
for i in 0 ..< N:
|
||||
# you can index an array with byte/uint8 but not a seq :/
|
||||
result[2*i] = hexChars[int ba[i] shr 4 and 0xF]
|
||||
result[2*i+1] = hexChars[int ba[i] and 0xF]
|
Loading…
x
Reference in New Issue
Block a user