193a7f9f77ea5929936b986be179d15111ffb88c
[fio.git] / t / lfsr-test.c
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
12 void 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
25 int 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
97         /* Check if all expected numbers within range have been calculated */
98         r = 0;
99         if (verify) {
100                 fprintf(stderr, "Verifying results... ");
101                 for (i = 0; i < numbers; i++) {
102                         if (*(uint8_t *)(v + 1) != 1) {
103                                 fprintf(stderr, "failed.\n");
104                                 r = 1;
105                                 break;
106                         }
107                 }
108                 if (!r)
109                         fprintf(stderr, "OK!\n");
110         }
111
112         /* Calculate elapsed time and mean time per number */
113         total = (end.tv_sec - start.tv_sec) * pow(10,9) +
114                 end.tv_nsec - start.tv_nsec;
115         mean = total / fl->num_vals;
116
117         printf("\nTime results ");
118         if (verify)
119                 printf("(slower due to verification)");
120         printf("\n==============================\n");
121         printf("Elapsed: %lf s\n", total / pow(10,9));
122         printf("Mean:    %lf ns\n", mean);
123
124         free(v_start);
125         free(fl);
126         return r;
127 }