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