2 * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
3 * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
4 * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
8 * Performs timing for gf arithmetic
13 #ifdef HAVE_POSIX_MEMALIGN
15 #define _XOPEN_SOURCE 600
26 #include "gf_complete.h"
27 #include "gf_method.h"
29 #include "gf_general.h"
32 timer_start (double *t)
36 gettimeofday (&tv, NULL);
37 *t = (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
41 timer_split (const double *t)
46 gettimeofday (&tv, NULL);
47 cur_t = (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
53 fprintf(stderr, "Timing test failed.\n");
54 fprintf(stderr, "%s\n", s);
58 char *BM = "Bad Method: ";
62 fprintf(stderr, "usage: gf_time w tests seed size(bytes) iterations [method [params]] - does timing\n");
63 fprintf(stderr, "\n");
64 fprintf(stderr, "does unit testing in GF(2^w)\n");
65 fprintf(stderr, "\n");
66 fprintf(stderr, "Legal w are: 1 - 32, 64 and 128\n");
67 fprintf(stderr, "\n");
68 fprintf(stderr, "Tests may be any combination of:\n");
69 fprintf(stderr, " A: All\n");
70 fprintf(stderr, " S: All Single Operations\n");
71 fprintf(stderr, " R: All Region Operations\n");
72 fprintf(stderr, " M: Single: Multiplications\n");
73 fprintf(stderr, " D: Single: Divisions\n");
74 fprintf(stderr, " I: Single: Inverses\n");
75 fprintf(stderr, " G: Region: Buffer-Constant Multiplication\n");
76 fprintf(stderr, " 0: Region: Doing nothing, and bzero()\n");
77 fprintf(stderr, " 1: Region: Memcpy() and XOR\n");
78 fprintf(stderr, " 2: Region: Multiplying by two\n");
79 fprintf(stderr, "\n");
80 fprintf(stderr, "Use -1 for time(0) as a seed.\n");
81 fprintf(stderr, "\n");
83 fprintf(stderr, "%s", BM);
85 } else if (s != NULL) {
86 fprintf(stderr, "%s\n", s);
91 int main(int argc, char **argv)
93 int w, it, i, size, iterations, xor;
96 char *single_tests = "MDI";
97 char *region_tests = "G012";
101 double timer, elapsed, ds, di, dnum;
106 #ifndef HAVE_POSIX_MEMALIGN
107 uint8_t *malloc_ra, *malloc_rb;
111 if (argc < 6) usage(NULL);
113 if (sscanf(argv[1], "%d", &w) == 0){
114 usage("Bad w[-pp]\n");
118 if (sscanf(argv[3], "%ld", &t0) == 0) usage("Bad seed\n");
119 if (sscanf(argv[4], "%d", &size) == 0) usage("Bad size\n");
120 if (sscanf(argv[5], "%d", &iterations) == 0) usage("Bad iterations\n");
121 if (t0 == -1) t0 = time(0);
127 if ((w > 32 && w != 64 && w != 128) || w < 0) usage("Bad w");
128 if ((size * 8) % w != 0) usage ("Bad size -- must be a multiple of w*8\n");
130 if (!create_gf_from_argv(&gf, w, argc, argv, 6)) usage(BM);
133 for (i = 0; argv[2][i] != '\0'; i++) {
135 case 'A': strcat(tests, single_tests);
136 strcat(tests, region_tests);
138 case 'S': strcat(tests, single_tests); break;
139 case 'R': strcat(tests, region_tests); break;
140 case 'G': strcat(tests, "G"); break;
141 case '0': strcat(tests, "0"); break;
142 case '1': strcat(tests, "1"); break;
143 case '2': strcat(tests, "2"); break;
144 case 'M': strcat(tests, "M"); break;
145 case 'D': strcat(tests, "D"); break;
146 case 'I': strcat(tests, "I"); break;
147 default: usage("Bad tests");
151 tstrings['M'] = "Multiply";
152 tstrings['D'] = "Divide";
153 tstrings['I'] = "Inverse";
154 tstrings['G'] = "Region-Random";
155 tstrings['0'] = "Region-By-Zero";
156 tstrings['1'] = "Region-By-One";
157 tstrings['2'] = "Region-By-Two";
159 tmethods['M'] = (void *) gf.multiply.w32;
160 tmethods['D'] = (void *) gf.divide.w32;
161 tmethods['I'] = (void *) gf.inverse.w32;
162 tmethods['G'] = (void *) gf.multiply_region.w32;
163 tmethods['0'] = (void *) gf.multiply_region.w32;
164 tmethods['1'] = (void *) gf.multiply_region.w32;
165 tmethods['2'] = (void *) gf.multiply_region.w32;
167 printf("Seed: %ld\n", t0);
169 #ifdef HAVE_POSIX_MEMALIGN
170 if (posix_memalign((void **) &ra, 16, size))
172 if (posix_memalign((void **) &rb, 16, size))
175 malloc_ra = (uint8_t *) malloc(size + 15);
176 malloc_rb = (uint8_t *) malloc(size + 15);
177 ra = (uint8_t *) (((uintptr_t) malloc_ra + 15) & ~((uintptr_t) 0xf));
178 rb = (uint8_t *) (((uintptr_t) malloc_rb + 15) & ~((uintptr_t) 0xf));
181 if (ra == NULL || rb == NULL) { perror("malloc"); exit(1); }
183 for (i = 0; i < 3; i++) {
184 test = single_tests[i];
185 if (strchr(tests, test) != NULL) {
186 if (tmethods[(int)test] == NULL) {
187 printf("No %s method.\n", tstrings[(int)test]);
191 for (it = 0; it < iterations; it++) {
192 gf_general_set_up_single_timing_test(w, ra, rb, size);
194 num = gf_general_do_single_timing_test(&gf, ra, rb, size, test);
196 elapsed += timer_split(&timer);
198 printf("%14s: %10.6lf s Mops: %10.3lf %10.3lf Mega-ops/s\n",
199 tstrings[(int)test], elapsed,
200 dnum/1024.0/1024.0, dnum/1024.0/1024.0/elapsed);
205 for (i = 0; i < 4; i++) {
206 test = region_tests[i];
207 if (strchr(tests, test) != NULL) {
208 if (tmethods[(int)test] == NULL) {
209 printf("No %s method.\n", tstrings[(int)test]);
211 if (test == '0') gf_general_set_zero(&a, w);
212 if (test == '1') gf_general_set_one(&a, w);
213 if (test == '2') gf_general_set_two(&a, w);
215 for (xor = 0; xor < 2; xor++) {
217 for (it = 0; it < iterations; it++) {
218 if (test == 'G') gf_general_set_random(&a, w, 1);
219 gf_general_set_up_single_timing_test(8, ra, rb, size);
221 gf_general_do_region_multiply(&gf, &a, ra, rb, size, xor);
222 elapsed += timer_split(&timer);
224 printf("%14s: XOR: %d %10.6lf s MB: %10.3lf %10.3lf MB/s\n",
225 tstrings[(int)test], xor, elapsed,
226 ds*di/1024.0/1024.0, ds*di/1024.0/1024.0/elapsed);