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