Skip to content

Commit fb54ce0

Browse files
committed
bench: add benchmarks for constituent hash algorithms for proof of work
This is to help us inform our decisions when deciding which code to remove and if our optimizations work as intended and where.
1 parent ee6efaa commit fb54ce0

File tree

2 files changed

+333
-0
lines changed

2 files changed

+333
-0
lines changed

src/Makefile.bench.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ bench_bench_dash_SOURCES = \
4343
bench/nanobench.cpp \
4444
bench/peer_eviction.cpp \
4545
bench/pool.cpp \
46+
bench/pow_hash.cpp \
4647
bench/rpc_blockchain.cpp \
4748
bench/rpc_mempool.cpp \
4849
bench/strencodings.cpp \

src/bench/pow_hash.cpp

Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
// Copyright (c) 2025 The Dash Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <bench/bench.h>
6+
7+
#include <crypto/x11/sph_blake.h>
8+
#include <crypto/x11/sph_bmw.h>
9+
#include <crypto/x11/sph_cubehash.h>
10+
#include <crypto/x11/sph_echo.h>
11+
#include <crypto/x11/sph_groestl.h>
12+
#include <crypto/x11/sph_jh.h>
13+
#include <crypto/x11/sph_keccak.h>
14+
#include <crypto/x11/sph_luffa.h>
15+
#include <crypto/x11/sph_shavite.h>
16+
#include <crypto/x11/sph_simd.h>
17+
#include <crypto/x11/sph_skein.h>
18+
19+
namespace {
20+
//! Bytes to hash per iteration
21+
static constexpr size_t BUFFER_SIZE{1000*1000};
22+
//! Bytes required to represent 512-bit unsigned integers (uint512)
23+
static constexpr size_t OUTPUT_SIZE{64};
24+
25+
inline void Pow_Blake512(benchmark::Bench& bench, const size_t bytes)
26+
{
27+
sph_blake512_context ctx;
28+
uint8_t hash[OUTPUT_SIZE];
29+
std::vector<uint8_t> in(bytes, 0);
30+
bench.batch(in.size()).unit("byte").run([&] {
31+
sph_blake512_init(&ctx);
32+
sph_blake512(&ctx, in.data(), in.size());
33+
sph_blake512_close(&ctx, &hash);
34+
});
35+
}
36+
37+
inline void Pow_Bmw512(benchmark::Bench& bench, const size_t bytes)
38+
{
39+
sph_bmw512_context ctx;
40+
uint8_t hash[OUTPUT_SIZE];
41+
std::vector<uint8_t> in(bytes, 0);
42+
bench.batch(in.size()).unit("byte").run([&] {
43+
sph_bmw512_init(&ctx);
44+
sph_bmw512(&ctx, in.data(), in.size());
45+
sph_bmw512_close(&ctx, &hash);
46+
});
47+
}
48+
49+
inline void Pow_Cubehash512(benchmark::Bench& bench, const size_t bytes)
50+
{
51+
sph_cubehash512_context ctx;
52+
uint8_t hash[OUTPUT_SIZE];
53+
std::vector<uint8_t> in(bytes, 0);
54+
bench.batch(in.size()).unit("byte").run([&] {
55+
sph_cubehash512_init(&ctx);
56+
sph_cubehash512(&ctx, in.data(), in.size());
57+
sph_cubehash512_close(&ctx, &hash);
58+
});
59+
}
60+
61+
inline void Pow_Echo512(benchmark::Bench& bench, const size_t bytes)
62+
{
63+
sph_echo512_context ctx;
64+
uint8_t hash[OUTPUT_SIZE];
65+
std::vector<uint8_t> in(bytes, 0);
66+
bench.batch(in.size()).unit("byte").run([&] {
67+
sph_echo512_init(&ctx);
68+
sph_echo512(&ctx, in.data(), in.size());
69+
sph_echo512_close(&ctx, &hash);
70+
});
71+
}
72+
73+
inline void Pow_Groestl512(benchmark::Bench& bench, const size_t bytes)
74+
{
75+
sph_groestl512_context ctx;
76+
uint8_t hash[OUTPUT_SIZE];
77+
std::vector<uint8_t> in(bytes, 0);
78+
bench.batch(in.size()).unit("byte").run([&] {
79+
sph_groestl512_init(&ctx);
80+
sph_groestl512(&ctx, in.data(), in.size());
81+
sph_groestl512_close(&ctx, &hash);
82+
});
83+
}
84+
85+
inline void Pow_Jh512(benchmark::Bench& bench, const size_t bytes)
86+
{
87+
sph_jh512_context ctx;
88+
uint8_t hash[OUTPUT_SIZE];
89+
std::vector<uint8_t> in(bytes, 0);
90+
bench.batch(in.size()).unit("byte").run([&] {
91+
sph_jh512_init(&ctx);
92+
sph_jh512(&ctx, in.data(), in.size());
93+
sph_jh512_close(&ctx, &hash);
94+
});
95+
}
96+
97+
inline void Pow_Keccak512(benchmark::Bench& bench, const size_t bytes)
98+
{
99+
sph_keccak512_context ctx;
100+
uint8_t hash[OUTPUT_SIZE];
101+
std::vector<uint8_t> in(bytes, 0);
102+
bench.batch(in.size()).unit("byte").run([&] {
103+
sph_keccak512_init(&ctx);
104+
sph_keccak512(&ctx, in.data(), in.size());
105+
sph_keccak512_close(&ctx, &hash);
106+
});
107+
}
108+
109+
inline void Pow_Luffa512(benchmark::Bench& bench, const size_t bytes)
110+
{
111+
sph_luffa512_context ctx;
112+
uint8_t hash[OUTPUT_SIZE];
113+
std::vector<uint8_t> in(bytes, 0);
114+
bench.batch(in.size()).unit("byte").run([&] {
115+
sph_luffa512_init(&ctx);
116+
sph_luffa512(&ctx, in.data(), in.size());
117+
sph_luffa512_close(&ctx, &hash);
118+
});
119+
}
120+
121+
inline void Pow_Shavite512(benchmark::Bench& bench, const size_t bytes)
122+
{
123+
sph_shavite512_context ctx;
124+
uint8_t hash[OUTPUT_SIZE];
125+
std::vector<uint8_t> in(bytes, 0);
126+
bench.batch(in.size()).unit("byte").run([&] {
127+
sph_shavite512_init(&ctx);
128+
sph_shavite512(&ctx, in.data(), in.size());
129+
sph_shavite512_close(&ctx, &hash);
130+
});
131+
}
132+
133+
inline void Pow_Simd512(benchmark::Bench& bench, const size_t bytes)
134+
{
135+
sph_simd512_context ctx;
136+
uint8_t hash[OUTPUT_SIZE];
137+
std::vector<uint8_t> in(bytes, 0);
138+
bench.batch(in.size()).unit("byte").run([&] {
139+
sph_simd512_init(&ctx);
140+
sph_simd512(&ctx, in.data(), in.size());
141+
sph_simd512_close(&ctx, &hash);
142+
});
143+
}
144+
145+
inline void Pow_Skein512(benchmark::Bench& bench, const size_t bytes)
146+
{
147+
sph_skein512_context ctx;
148+
uint8_t hash[OUTPUT_SIZE];
149+
std::vector<uint8_t> in(bytes, 0);
150+
bench.batch(in.size()).unit("byte").run([&] {
151+
sph_skein512_init(&ctx);
152+
sph_skein512(&ctx, in.data(), in.size());
153+
sph_skein512_close(&ctx, &hash);
154+
});
155+
}
156+
} // anonymous namespace
157+
158+
static void Pow_Blake512_0032b(benchmark::Bench& bench) { return Pow_Blake512(bench, 32); }
159+
static void Pow_Blake512_0080b(benchmark::Bench& bench) { return Pow_Blake512(bench, 80); }
160+
static void Pow_Blake512_0128b(benchmark::Bench& bench) { return Pow_Blake512(bench, 128); }
161+
static void Pow_Blake512_0512b(benchmark::Bench& bench) { return Pow_Blake512(bench, 512); }
162+
static void Pow_Blake512_1024b(benchmark::Bench& bench) { return Pow_Blake512(bench, 1024); }
163+
static void Pow_Blake512_2048b(benchmark::Bench& bench) { return Pow_Blake512(bench, 2048); }
164+
static void Pow_Blake512_1M(benchmark::Bench& bench) { return Pow_Blake512(bench, BUFFER_SIZE); }
165+
166+
static void Pow_Bmw512_0032b(benchmark::Bench& bench) { return Pow_Bmw512(bench, 32); }
167+
static void Pow_Bmw512_0080b(benchmark::Bench& bench) { return Pow_Bmw512(bench, 80); }
168+
static void Pow_Bmw512_0128b(benchmark::Bench& bench) { return Pow_Bmw512(bench, 128); }
169+
static void Pow_Bmw512_0512b(benchmark::Bench& bench) { return Pow_Bmw512(bench, 512); }
170+
static void Pow_Bmw512_1024b(benchmark::Bench& bench) { return Pow_Bmw512(bench, 1024); }
171+
static void Pow_Bmw512_2048b(benchmark::Bench& bench) { return Pow_Bmw512(bench, 2048); }
172+
static void Pow_Bmw512_1M(benchmark::Bench& bench) { return Pow_Bmw512(bench, BUFFER_SIZE); }
173+
174+
static void Pow_Cubehash512_0032b(benchmark::Bench& bench) { return Pow_Cubehash512(bench, 32); }
175+
static void Pow_Cubehash512_0080b(benchmark::Bench& bench) { return Pow_Cubehash512(bench, 80); }
176+
static void Pow_Cubehash512_0128b(benchmark::Bench& bench) { return Pow_Cubehash512(bench, 128); }
177+
static void Pow_Cubehash512_0512b(benchmark::Bench& bench) { return Pow_Cubehash512(bench, 512); }
178+
static void Pow_Cubehash512_1024b(benchmark::Bench& bench) { return Pow_Cubehash512(bench, 1024); }
179+
static void Pow_Cubehash512_2048b(benchmark::Bench& bench) { return Pow_Cubehash512(bench, 2048); }
180+
static void Pow_Cubehash512_1M(benchmark::Bench& bench) { return Pow_Cubehash512(bench, BUFFER_SIZE); }
181+
182+
static void Pow_Echo512_0032b(benchmark::Bench& bench) { return Pow_Echo512(bench, 32); }
183+
static void Pow_Echo512_0080b(benchmark::Bench& bench) { return Pow_Echo512(bench, 80); }
184+
static void Pow_Echo512_0128b(benchmark::Bench& bench) { return Pow_Echo512(bench, 128); }
185+
static void Pow_Echo512_0512b(benchmark::Bench& bench) { return Pow_Echo512(bench, 512); }
186+
static void Pow_Echo512_1024b(benchmark::Bench& bench) { return Pow_Echo512(bench, 1024); }
187+
static void Pow_Echo512_2048b(benchmark::Bench& bench) { return Pow_Echo512(bench, 2048); }
188+
static void Pow_Echo512_1M(benchmark::Bench& bench) { return Pow_Echo512(bench, BUFFER_SIZE); }
189+
190+
static void Pow_Groestl512_0032b(benchmark::Bench& bench) { return Pow_Groestl512(bench, 32); }
191+
static void Pow_Groestl512_0080b(benchmark::Bench& bench) { return Pow_Groestl512(bench, 80); }
192+
static void Pow_Groestl512_0128b(benchmark::Bench& bench) { return Pow_Groestl512(bench, 128); }
193+
static void Pow_Groestl512_0512b(benchmark::Bench& bench) { return Pow_Groestl512(bench, 512); }
194+
static void Pow_Groestl512_1024b(benchmark::Bench& bench) { return Pow_Groestl512(bench, 1024); }
195+
static void Pow_Groestl512_2048b(benchmark::Bench& bench) { return Pow_Groestl512(bench, 2048); }
196+
static void Pow_Groestl512_1M(benchmark::Bench& bench) { return Pow_Groestl512(bench, BUFFER_SIZE); }
197+
198+
static void Pow_Jh512_0032b(benchmark::Bench& bench) { return Pow_Jh512(bench, 32); }
199+
static void Pow_Jh512_0080b(benchmark::Bench& bench) { return Pow_Jh512(bench, 80); }
200+
static void Pow_Jh512_0128b(benchmark::Bench& bench) { return Pow_Jh512(bench, 128); }
201+
static void Pow_Jh512_0512b(benchmark::Bench& bench) { return Pow_Jh512(bench, 512); }
202+
static void Pow_Jh512_1024b(benchmark::Bench& bench) { return Pow_Jh512(bench, 1024); }
203+
static void Pow_Jh512_2048b(benchmark::Bench& bench) { return Pow_Jh512(bench, 2048); }
204+
static void Pow_Jh512_1M(benchmark::Bench& bench) { return Pow_Jh512(bench, BUFFER_SIZE); }
205+
206+
static void Pow_Keccak512_0032b(benchmark::Bench& bench) { return Pow_Keccak512(bench, 32); }
207+
static void Pow_Keccak512_0080b(benchmark::Bench& bench) { return Pow_Keccak512(bench, 80); }
208+
static void Pow_Keccak512_0128b(benchmark::Bench& bench) { return Pow_Keccak512(bench, 128); }
209+
static void Pow_Keccak512_0512b(benchmark::Bench& bench) { return Pow_Keccak512(bench, 512); }
210+
static void Pow_Keccak512_1024b(benchmark::Bench& bench) { return Pow_Keccak512(bench, 1024); }
211+
static void Pow_Keccak512_2048b(benchmark::Bench& bench) { return Pow_Keccak512(bench, 2048); }
212+
static void Pow_Keccak512_1M(benchmark::Bench& bench) { return Pow_Keccak512(bench, BUFFER_SIZE); }
213+
214+
static void Pow_Luffa512_0032b(benchmark::Bench& bench) { return Pow_Luffa512(bench, 32); }
215+
static void Pow_Luffa512_0080b(benchmark::Bench& bench) { return Pow_Luffa512(bench, 80); }
216+
static void Pow_Luffa512_0128b(benchmark::Bench& bench) { return Pow_Luffa512(bench, 128); }
217+
static void Pow_Luffa512_0512b(benchmark::Bench& bench) { return Pow_Luffa512(bench, 512); }
218+
static void Pow_Luffa512_1024b(benchmark::Bench& bench) { return Pow_Luffa512(bench, 1024); }
219+
static void Pow_Luffa512_2048b(benchmark::Bench& bench) { return Pow_Luffa512(bench, 2048); }
220+
static void Pow_Luffa512_1M(benchmark::Bench& bench) { return Pow_Luffa512(bench, BUFFER_SIZE); }
221+
222+
static void Pow_Shavite512_0032b(benchmark::Bench& bench) { return Pow_Shavite512(bench, 32); }
223+
static void Pow_Shavite512_0080b(benchmark::Bench& bench) { return Pow_Shavite512(bench, 80); }
224+
static void Pow_Shavite512_0128b(benchmark::Bench& bench) { return Pow_Shavite512(bench, 128); }
225+
static void Pow_Shavite512_0512b(benchmark::Bench& bench) { return Pow_Shavite512(bench, 512); }
226+
static void Pow_Shavite512_1024b(benchmark::Bench& bench) { return Pow_Shavite512(bench, 1024); }
227+
static void Pow_Shavite512_2048b(benchmark::Bench& bench) { return Pow_Shavite512(bench, 2048); }
228+
static void Pow_Shavite512_1M(benchmark::Bench& bench) { return Pow_Shavite512(bench, BUFFER_SIZE); }
229+
230+
static void Pow_Simd512_0032b(benchmark::Bench& bench) { return Pow_Simd512(bench, 32); }
231+
static void Pow_Simd512_0080b(benchmark::Bench& bench) { return Pow_Simd512(bench, 80); }
232+
static void Pow_Simd512_0128b(benchmark::Bench& bench) { return Pow_Simd512(bench, 128); }
233+
static void Pow_Simd512_0512b(benchmark::Bench& bench) { return Pow_Simd512(bench, 512); }
234+
static void Pow_Simd512_1024b(benchmark::Bench& bench) { return Pow_Simd512(bench, 1024); }
235+
static void Pow_Simd512_2048b(benchmark::Bench& bench) { return Pow_Simd512(bench, 2048); }
236+
static void Pow_Simd512_1M(benchmark::Bench& bench) { return Pow_Simd512(bench, BUFFER_SIZE); }
237+
238+
static void Pow_Skein512_0032b(benchmark::Bench& bench) { return Pow_Skein512(bench, 32); }
239+
static void Pow_Skein512_0080b(benchmark::Bench& bench) { return Pow_Skein512(bench, 80); }
240+
static void Pow_Skein512_0128b(benchmark::Bench& bench) { return Pow_Skein512(bench, 128); }
241+
static void Pow_Skein512_0512b(benchmark::Bench& bench) { return Pow_Skein512(bench, 512); }
242+
static void Pow_Skein512_1024b(benchmark::Bench& bench) { return Pow_Skein512(bench, 1024); }
243+
static void Pow_Skein512_2048b(benchmark::Bench& bench) { return Pow_Skein512(bench, 2048); }
244+
static void Pow_Skein512_1M(benchmark::Bench& bench) { return Pow_Skein512(bench, BUFFER_SIZE); }
245+
246+
BENCHMARK(Pow_Blake512_0032b);
247+
BENCHMARK(Pow_Blake512_0080b);
248+
BENCHMARK(Pow_Blake512_0128b);
249+
BENCHMARK(Pow_Blake512_0512b);
250+
BENCHMARK(Pow_Blake512_1024b);
251+
BENCHMARK(Pow_Blake512_2048b);
252+
BENCHMARK(Pow_Blake512_1M);
253+
254+
BENCHMARK(Pow_Bmw512_0032b);
255+
BENCHMARK(Pow_Bmw512_0080b);
256+
BENCHMARK(Pow_Bmw512_0128b);
257+
BENCHMARK(Pow_Bmw512_0512b);
258+
BENCHMARK(Pow_Bmw512_1024b);
259+
BENCHMARK(Pow_Bmw512_2048b);
260+
BENCHMARK(Pow_Bmw512_1M);
261+
262+
BENCHMARK(Pow_Cubehash512_0032b);
263+
BENCHMARK(Pow_Cubehash512_0080b);
264+
BENCHMARK(Pow_Cubehash512_0128b);
265+
BENCHMARK(Pow_Cubehash512_0512b);
266+
BENCHMARK(Pow_Cubehash512_1024b);
267+
BENCHMARK(Pow_Cubehash512_2048b);
268+
BENCHMARK(Pow_Cubehash512_1M);
269+
270+
BENCHMARK(Pow_Echo512_0032b);
271+
BENCHMARK(Pow_Echo512_0080b);
272+
BENCHMARK(Pow_Echo512_0128b);
273+
BENCHMARK(Pow_Echo512_0512b);
274+
BENCHMARK(Pow_Echo512_1024b);
275+
BENCHMARK(Pow_Echo512_2048b);
276+
BENCHMARK(Pow_Echo512_1M);
277+
278+
BENCHMARK(Pow_Groestl512_0032b);
279+
BENCHMARK(Pow_Groestl512_0080b);
280+
BENCHMARK(Pow_Groestl512_0128b);
281+
BENCHMARK(Pow_Groestl512_0512b);
282+
BENCHMARK(Pow_Groestl512_1024b);
283+
BENCHMARK(Pow_Groestl512_2048b);
284+
BENCHMARK(Pow_Groestl512_1M);
285+
286+
BENCHMARK(Pow_Jh512_0032b);
287+
BENCHMARK(Pow_Jh512_0080b);
288+
BENCHMARK(Pow_Jh512_0128b);
289+
BENCHMARK(Pow_Jh512_0512b);
290+
BENCHMARK(Pow_Jh512_1024b);
291+
BENCHMARK(Pow_Jh512_2048b);
292+
BENCHMARK(Pow_Jh512_1M);
293+
294+
BENCHMARK(Pow_Keccak512_0032b);
295+
BENCHMARK(Pow_Keccak512_0080b);
296+
BENCHMARK(Pow_Keccak512_0128b);
297+
BENCHMARK(Pow_Keccak512_0512b);
298+
BENCHMARK(Pow_Keccak512_1024b);
299+
BENCHMARK(Pow_Keccak512_2048b);
300+
BENCHMARK(Pow_Keccak512_1M);
301+
302+
BENCHMARK(Pow_Luffa512_0032b);
303+
BENCHMARK(Pow_Luffa512_0080b);
304+
BENCHMARK(Pow_Luffa512_0128b);
305+
BENCHMARK(Pow_Luffa512_0512b);
306+
BENCHMARK(Pow_Luffa512_1024b);
307+
BENCHMARK(Pow_Luffa512_2048b);
308+
BENCHMARK(Pow_Luffa512_1M);
309+
310+
BENCHMARK(Pow_Shavite512_0032b);
311+
BENCHMARK(Pow_Shavite512_0080b);
312+
BENCHMARK(Pow_Shavite512_0128b);
313+
BENCHMARK(Pow_Shavite512_0512b);
314+
BENCHMARK(Pow_Shavite512_1024b);
315+
BENCHMARK(Pow_Shavite512_2048b);
316+
BENCHMARK(Pow_Shavite512_1M);
317+
318+
BENCHMARK(Pow_Simd512_0032b);
319+
BENCHMARK(Pow_Simd512_0080b);
320+
BENCHMARK(Pow_Simd512_0128b);
321+
BENCHMARK(Pow_Simd512_0512b);
322+
BENCHMARK(Pow_Simd512_1024b);
323+
BENCHMARK(Pow_Simd512_2048b);
324+
BENCHMARK(Pow_Simd512_1M);
325+
326+
BENCHMARK(Pow_Skein512_0032b);
327+
BENCHMARK(Pow_Skein512_0080b);
328+
BENCHMARK(Pow_Skein512_0128b);
329+
BENCHMARK(Pow_Skein512_0512b);
330+
BENCHMARK(Pow_Skein512_1024b);
331+
BENCHMARK(Pow_Skein512_2048b);
332+
BENCHMARK(Pow_Skein512_1M);

0 commit comments

Comments
 (0)