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