Commit | Line | Data |
---|---|---|
7a887ffe AP |
1 | #include <stdio.h> |
2 | #include <stdlib.h> | |
7a887ffe AP |
3 | #include <math.h> |
4 | #include <string.h> | |
7a887ffe AP |
5 | |
6 | #include "../lib/lfsr.h" | |
48b944c4 JA |
7 | #include "../gettime.h" |
8 | #include "../fio_time.h" | |
db83b0ab | 9 | #include "../compiler/compiler.h" |
7a887ffe | 10 | |
ca0a0b52 | 11 | static void usage(void) |
7a887ffe AP |
12 | { |
13 | printf("Usage: lfsr-test 0x<numbers> [seed] [spin] [verify]\n"); | |
14 | printf("-------------------------------------------------------------\n"); | |
15 | printf("*numbers: how many random numbers to produce (in hex)\n" | |
16 | "seed: initial value\n" | |
17 | "spin: how many iterations before we produce a number\n" | |
18 | "verify: check if LFSR has iterated correctly\n\n" | |
19 | "Only <numbers> is required. The rest are evaluated to 0 or false\n" | |
20 | "Elapsed/mean time and verification results are printed at the" | |
21 | "end of the test\n"); | |
22 | } | |
23 | ||
24 | int main(int argc, char *argv[]) | |
25 | { | |
26 | int r; | |
8b6a404c | 27 | struct timespec start, end; |
7a887ffe AP |
28 | struct fio_lfsr *fl; |
29 | int verify = 0; | |
30 | unsigned int spin = 0; | |
31 | uint64_t seed = 0; | |
32 | uint64_t numbers; | |
33 | uint64_t v_size; | |
34 | uint64_t i; | |
35 | void *v = NULL, *v_start; | |
36 | double total, mean; | |
37 | ||
71471cb1 JA |
38 | arch_init(argv); |
39 | ||
7a887ffe AP |
40 | /* Read arguments */ |
41 | switch (argc) { | |
42 | case 5: if (strncmp(argv[4], "verify", 7) == 0) | |
24010223 | 43 | verify = 1; |
db83b0ab | 44 | fallthrough; |
7a887ffe | 45 | case 4: spin = atoi(argv[3]); |
db83b0ab | 46 | fallthrough; |
7a887ffe | 47 | case 3: seed = atol(argv[2]); |
db83b0ab | 48 | fallthrough; |
7a887ffe AP |
49 | case 2: numbers = strtol(argv[1], NULL, 16); |
50 | break; | |
51 | default: usage(); | |
52 | return 1; | |
53 | } | |
54 | ||
55 | /* Initialize LFSR */ | |
56 | fl = malloc(sizeof(struct fio_lfsr)); | |
57 | if (!fl) { | |
58 | perror("malloc"); | |
59 | return 1; | |
60 | } | |
61 | ||
62 | r = lfsr_init(fl, numbers, seed, spin); | |
63 | if (r) { | |
64 | printf("Initialization failed.\n"); | |
65 | return r; | |
66 | } | |
67 | ||
68 | /* Print specs */ | |
69 | printf("LFSR specs\n"); | |
70 | printf("==========================\n"); | |
71 | printf("Size is %u\n", 64 - __builtin_clzl(fl->cached_bit)); | |
761c2729 JA |
72 | printf("Max val is %lu\n", (unsigned long) fl->max_val); |
73 | printf("XOR-mask is 0x%lX\n", (unsigned long) fl->xormask); | |
74 | printf("Seed is %lu\n", (unsigned long) fl->last_val); | |
7a887ffe | 75 | printf("Spin is %u\n", fl->spin); |
761c2729 | 76 | printf("Cycle length is %lu\n", (unsigned long) fl->cycle_length); |
7a887ffe AP |
77 | |
78 | /* Create verification table */ | |
79 | if (verify) { | |
80 | v_size = numbers * sizeof(uint8_t); | |
81 | v = malloc(v_size); | |
82 | memset(v, 0, v_size); | |
4870138d | 83 | printf("\nVerification table is %lf KiB\n", (double)(v_size) / 1024); |
7a887ffe AP |
84 | } |
85 | v_start = v; | |
86 | ||
87 | /* | |
88 | * Iterate over a tight loop until we have produced all the requested | |
89 | * numbers. Verifying the results should introduce some small yet not | |
90 | * negligible overhead. | |
91 | */ | |
92 | fprintf(stderr, "\nTest initiated... "); | |
9077ee4a | 93 | fio_gettime(&start, NULL); |
dd9bd2b2 | 94 | while (!lfsr_next(fl, &i)) { |
7a887ffe AP |
95 | if (verify) |
96 | *(uint8_t *)(v + i) += 1; | |
97 | } | |
9077ee4a | 98 | fio_gettime(&end, NULL); |
7a887ffe AP |
99 | fprintf(stderr, "finished.\n"); |
100 | ||
d0f85362 | 101 | |
7a887ffe AP |
102 | /* Check if all expected numbers within range have been calculated */ |
103 | r = 0; | |
104 | if (verify) { | |
105 | fprintf(stderr, "Verifying results... "); | |
106 | for (i = 0; i < numbers; i++) { | |
d0f85362 AP |
107 | if (*(uint8_t *)(v + i) != 1) { |
108 | fprintf(stderr, "failed (%lu = %d).\n", | |
761c2729 JA |
109 | (unsigned long) i, |
110 | *(uint8_t *)(v + i)); | |
7a887ffe AP |
111 | r = 1; |
112 | break; | |
113 | } | |
114 | } | |
115 | if (!r) | |
116 | fprintf(stderr, "OK!\n"); | |
117 | } | |
118 | ||
119 | /* Calculate elapsed time and mean time per number */ | |
48b944c4 | 120 | total = utime_since(&start, &end); |
7a887ffe AP |
121 | mean = total / fl->num_vals; |
122 | ||
123 | printf("\nTime results "); | |
124 | if (verify) | |
125 | printf("(slower due to verification)"); | |
126 | printf("\n==============================\n"); | |
036c8019 | 127 | printf("Elapsed: %lf s\n", total / pow(10,6)); |
48b944c4 | 128 | printf("Mean: %lf us\n", mean); |
7a887ffe AP |
129 | |
130 | free(v_start); | |
131 | free(fl); | |
132 | return r; | |
133 | } |