Skip to content

Conversation

@chfast
Copy link
Member

@chfast chfast commented May 29, 2018

I reimplemented Keccak main loop. This is only used in ethash cache generation. The time for epoch 200 drops from 1.8 s to 1.3 s.

Do not merge it yet.

@chfast chfast requested a review from karalabe as a code owner May 29, 2018 13:41
@fjl
Copy link
Contributor

fjl commented May 29, 2018

It looks like a lot of the overhead is due to Sum copying the state and allocating a temporary buffer for the result. We can avoid the overhead using this function:

func makeHasher(h hash.Hash) hasher {
	// If the hash supports Read to get the sum (like sha3.state), use it.
	// This avoids the overhead of Sum.
	type readerHash interface {
		hash.Hash
		Read([]byte) (int, error)
	}
	if rh, ok := h.(readerHash); ok {
		outputLen := rh.Size()
		return func(dest []byte, data []byte) {
			rh.Reset()
			rh.Write(data)
			rh.Read(dest[:outputLen])
		}
	}
	// Otherwise use Sum.
	return func(dest []byte, data []byte) {
		h.Reset()
		h.Write(data)
		h.Sum(dest[:0])
	}
}

Benchmark difference with this change:

name                      old time/op  new time/op  delta
CacheGeneration-8          764ms ± 1%   579ms ± 1%  -24.22%  (p=0.000 n=20+17)
SmallDatasetGeneration-8  75.2ms ±12%  60.6ms ±10%  -19.37%  (p=0.000 n=20+20)
HashimotoLight-8          1.58ms ±11%  1.55ms ± 8%     ~     (p=0.322 n=20+19)
HashimotoFullSmall-8      4.90µs ± 1%  4.88µs ± 1%   -0.31%  (p=0.013 n=19+18)

@fjl fjl closed this Jun 1, 2018
@chfast chfast deleted the optimize-keccak branch June 25, 2018 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants