lfsr-test.c revision d33388286b785748773c54f066319d37c66f8f91
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
14void 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
27int 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, fl->max_val)) {
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