1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
#include <time.h>
#include <string.h>
#include "argon2-impl-select.h"
#include "argon2.h"
#define BENCH_SAMPLES 512
#define BENCH_MEM_BLOCKS 512
static argon2_impl selected_argon_impl = {
"(default)", NULL, fill_segment_default
};
/* the benchmark routine is not thread-safe, so we can use a global var here: */
static block memory[BENCH_MEM_BLOCKS];
static uint64_t benchmark_impl(const argon2_impl *impl) {
clock_t time;
unsigned int i;
uint64_t bench;
argon2_instance_t instance;
argon2_position_t pos;
memset(memory, 0, sizeof(memory));
instance.version = ARGON2_VERSION_NUMBER;
instance.memory = memory;
instance.passes = 1;
instance.memory_blocks = BENCH_MEM_BLOCKS;
instance.segment_length = BENCH_MEM_BLOCKS / ARGON2_SYNC_POINTS;
instance.lane_length = instance.segment_length * ARGON2_SYNC_POINTS;
instance.lanes = 1;
instance.threads = 1;
instance.type = Argon2_i;
pos.lane = 0;
pos.pass = 0;
pos.slice = 0;
pos.index = 0;
/* warm-up cache: */
impl->fill_segment(&instance, pos);
/* OK, now measure: */
bench = 0;
time = clock();
for (i = 0; i < BENCH_SAMPLES; i++) {
impl->fill_segment(&instance, pos);
}
time = clock() - time;
bench = (uint64_t)time;
return bench;
}
static void select_impl(FILE *out, const char *prefix)
{
argon2_impl_list impls;
unsigned int i;
const argon2_impl *best_impl = NULL;
uint64_t best_bench = UINT_MAX;
argon2_get_impl_list(&impls);
for (i = 0; i < impls.count; i++) {
const argon2_impl *impl = &impls.entries[i];
uint64_t bench;
bench = benchmark_impl(impl);
if (bench < best_bench) {
best_bench = bench;
best_impl = impl;
}
}
if (best_impl != NULL) {
selected_argon_impl = *best_impl;
}
}
void fill_segment(const argon2_instance_t *instance, argon2_position_t position)
{
selected_argon_impl.fill_segment(instance, position);
}
void argon2_select_impl(FILE *out, const char *prefix)
{
if (prefix == NULL) {
prefix = "";
}
select_impl(out, prefix);
}
|