#include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include "../lib/lfsr.h" void usage() { printf("Usage: lfsr-test 0x<numbers> [seed] [spin] [verify]\n"); printf("-------------------------------------------------------------\n"); printf("*numbers: how many random numbers to produce (in hex)\n" "seed: initial value\n" "spin: how many iterations before we produce a number\n" "verify: check if LFSR has iterated correctly\n\n" "Only <numbers> is required. The rest are evaluated to 0 or false\n" "Elapsed/mean time and verification results are printed at the" "end of the test\n"); } int main(int argc, char *argv[]) { int r; struct timespec start, end; struct fio_lfsr *fl; int verify = 0; unsigned int spin = 0; uint64_t seed = 0; uint64_t numbers; uint64_t v_size; uint64_t i; void *v = NULL, *v_start; double total, mean; /* Read arguments */ switch (argc) { case 5: if (strncmp(argv[4], "verify", 7) == 0) verify = 1; case 4: spin = atoi(argv[3]); case 3: seed = atol(argv[2]); case 2: numbers = strtol(argv[1], NULL, 16); break; default: usage(); return 1; } /* Initialize LFSR */ fl = malloc(sizeof(struct fio_lfsr)); if (!fl) { perror("malloc"); return 1; } r = lfsr_init(fl, numbers, seed, spin); if (r) { printf("Initialization failed.\n"); return r; } /* Print specs */ printf("LFSR specs\n"); printf("==========================\n"); printf("Size is %u\n", 64 - __builtin_clzl(fl->cached_bit)); printf("Max val is %lu\n", fl->max_val); printf("XOR-mask is 0x%lX\n", fl->xormask); printf("Seed is %lu\n", fl->last_val); printf("Spin is %u\n", fl->spin); printf("Cycle length is %lu\n", fl->cycle_length); /* Create verification table */ if (verify) { v_size = numbers * sizeof(uint8_t); v = malloc(v_size); memset(v, 0, v_size); printf("\nVerification table is %lf KBs\n", (double)(v_size) / 1024); } v_start = v; /* * Iterate over a tight loop until we have produced all the requested * numbers. Verifying the results should introduce some small yet not * negligible overhead. */ fprintf(stderr, "\nTest initiated... "); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); while (!lfsr_next(fl, &i, fl->max_val)) { if (verify) *(uint8_t *)(v + i) += 1; } clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); fprintf(stderr, "finished.\n"); /* Check if all expected numbers within range have been calculated */ r = 0; if (verify) { fprintf(stderr, "Verifying results... "); for (i = 0; i < numbers; i++) { if (*(uint8_t *)(v + i) != 1) { fprintf(stderr, "failed (%lu = %d).\n", i, *(uint8_t *)(v + i)); r = 1; break; } } if (!r) fprintf(stderr, "OK!\n"); } /* Calculate elapsed time and mean time per number */ total = (end.tv_sec - start.tv_sec) * pow(10,9) + end.tv_nsec - start.tv_nsec; mean = total / fl->num_vals; printf("\nTime results "); if (verify) printf("(slower due to verification)"); printf("\n==============================\n"); printf("Elapsed: %lf s\n", total / pow(10,9)); printf("Mean: %lf ns\n", mean); free(v_start); free(fl); return r; }