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