]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 A |
1 | /* Copyright (c) 1998 Apple Computer, Inc. All rights reserved. |
2 | * | |
3 | * giantBench.c - Benchmark of NSGiantInteger primitives. | |
4 | * | |
5 | * Revision History | |
6 | * ---------------- | |
7 | * 13 Apr 98 Doug Mitchell at Apple | |
8 | * Created. | |
9 | */ | |
10 | ||
11 | #include "giantIntegers.h" | |
12 | #include "ckutilities.h" | |
13 | #include "feeFunctions.h" | |
14 | #include "feeDebug.h" | |
15 | #include <stdlib.h> | |
16 | #include "ckutilsPlatform.h" | |
17 | #include <stdio.h> | |
18 | #include <time.h> | |
19 | ||
20 | #define LOOPS_DEF 100 | |
21 | #define MIN_SIZE_DEF 4 /* min giant size in bytes */ | |
22 | #define MAX_SIZE_DEF 32 /* max in bytes */ | |
23 | #define LOOP_NOTIFY 100 | |
24 | ||
25 | ||
26 | static void usage(char **argv) | |
27 | { | |
28 | printf("usage: %s [options]\n", argv[0]); | |
29 | printf(" Options:\n"); | |
30 | printf(" l=loops (default = %d)\n", LOOPS_DEF); | |
31 | printf(" n=maxBytes (default = %d\n", MIN_SIZE_DEF); | |
32 | printf(" x=maxBytes (default = %d\n", MAX_SIZE_DEF); | |
33 | printf(" o (use old 16-bit CryptKit\n"); | |
34 | printf(" s=seed\n"); | |
35 | printf(" h(elp)\n"); | |
36 | exit(1); | |
37 | } | |
38 | ||
39 | /* | |
40 | * Fill buffer with random data. | |
41 | */ | |
42 | static void fillData(unsigned bufSize, | |
43 | unsigned char *buf) | |
44 | { | |
45 | unsigned *ip; | |
46 | unsigned intCount; | |
47 | unsigned residue; | |
48 | unsigned char *cp; | |
49 | int i; | |
50 | ||
51 | intCount = bufSize >> 2; | |
52 | ip = (unsigned *)buf; | |
53 | for(i=0; i<intCount; i++) { | |
54 | *ip++ = RAND(); | |
55 | } | |
56 | ||
57 | residue = bufSize & 0x3; | |
58 | cp = (unsigned char *)ip; | |
59 | for(i=0; i<residue; i++) { | |
60 | *cp++ = (unsigned char)RAND(); | |
61 | } | |
62 | } | |
63 | ||
64 | /* | |
65 | * fill a pre-allocd giant with specified number of bytes of random | |
66 | * data. *Buf is mallocd and uninitialized and will change here. | |
67 | */ | |
68 | static void genGiant(giant g, | |
69 | unsigned numBytes, | |
70 | unsigned char *buf) | |
71 | { | |
72 | int i; | |
73 | ||
74 | fillData(numBytes, buf); | |
75 | deserializeGiant(buf, g, numBytes); | |
76 | ||
77 | /* set random sign; deserializeGiant() is always positive */ | |
78 | i = RAND(); | |
79 | if(i & 1) { | |
80 | g->sign = -g->sign; | |
81 | } | |
82 | ||
83 | /* avoid zero data - too many pitfalls with mod and div */ | |
84 | while(isZero(g)) { | |
85 | g->sign = 1; | |
86 | g->n[0] = RAND(); | |
87 | } | |
88 | } | |
89 | ||
90 | /* | |
91 | * Init giant arrays with random data. | |
92 | */ | |
93 | static void initRandGiants(unsigned numBytes, | |
94 | unsigned char *buf, | |
95 | unsigned numGiants, | |
96 | giant *g1, | |
97 | giant *g2) | |
98 | { | |
99 | int i; | |
100 | ||
101 | for(i=0; i<numGiants; i++) { | |
102 | genGiant(g1[i], numBytes, buf); | |
103 | genGiant(g2[i], numBytes, buf); | |
104 | } | |
105 | } | |
106 | ||
107 | /* | |
108 | * Individual tests. API is identical for all tests. | |
109 | * | |
110 | * loops : number of ops to perform. | |
111 | * g1, g2 : arrays of giants with random data and sign. Tests may modify | |
112 | * these. Size of array = 'loops'. Capacity big enough for all | |
113 | * conceivable ops. | |
114 | * Return : total microseconds to do 'loops' ops. | |
115 | */ | |
116 | ||
117 | static int mulgTest(unsigned loops, | |
118 | giant *g1, | |
119 | giant *g2) | |
120 | { | |
121 | int loop; | |
122 | PLAT_TIME startTime; | |
123 | PLAT_TIME endTime; | |
124 | ||
125 | PLAT_GET_TIME(startTime); | |
126 | for(loop=0; loop<loops; loop++) { | |
127 | mulg(*g1++, *g2++); | |
128 | } | |
129 | PLAT_GET_TIME(endTime); | |
130 | return PLAT_GET_NS(startTime, endTime); | |
131 | } | |
132 | ||
133 | static int squareTest(unsigned loops, | |
134 | giant *g1, | |
135 | giant *g2) | |
136 | { | |
137 | int loop; | |
138 | PLAT_TIME startTime; | |
139 | PLAT_TIME endTime; | |
140 | ||
141 | PLAT_GET_TIME(startTime); | |
142 | for(loop=0; loop<loops; loop++) { | |
143 | gsquare(*g1++); | |
144 | } | |
145 | PLAT_GET_TIME(endTime); | |
146 | return PLAT_GET_NS(startTime, endTime); | |
147 | } | |
148 | ||
149 | ||
150 | int main(int argc, char **argv) | |
151 | { | |
152 | int arg; | |
153 | char *argp; | |
154 | giant *g1; | |
155 | giant *g2; // ditto | |
156 | unsigned char *buf; // random data | |
157 | unsigned numDigits; | |
158 | unsigned i; | |
159 | unsigned numBytes; | |
160 | unsigned mulgElapsed; | |
161 | unsigned sqrElapsed; | |
162 | ||
163 | int loops = LOOPS_DEF; | |
164 | int seedSpec = 0; | |
165 | unsigned seed = 0; | |
166 | unsigned maxSize = MAX_SIZE_DEF; | |
167 | unsigned minSize = MIN_SIZE_DEF; | |
168 | int useOld = 0; | |
169 | ||
170 | initCryptKit(); | |
171 | ||
172 | #if macintosh | |
173 | argc = ccommand(&argv); | |
174 | #endif | |
175 | ||
176 | for(arg=1; arg<argc; arg++) { | |
177 | argp = argv[arg]; | |
178 | switch(argp[0]) { | |
179 | case 'x': | |
180 | maxSize = atoi(&argp[2]); | |
181 | break; | |
182 | case 'n': | |
183 | minSize = atoi(&argp[2]); | |
184 | break; | |
185 | case 'l': | |
186 | loops = atoi(&argp[2]); | |
187 | break; | |
188 | case 'o': | |
189 | useOld = 1; | |
190 | break; | |
191 | case 's': | |
192 | seed = atoi(&argp[2]); | |
193 | seedSpec = 1; | |
194 | break; | |
195 | case 'h': | |
196 | default: | |
197 | usage(argv); | |
198 | } | |
199 | } | |
200 | buf = malloc(maxSize); | |
201 | ||
202 | if(!seedSpec) { | |
203 | unsigned long tim; | |
204 | time(&tim); | |
205 | seed = (unsigned)tim; | |
206 | } | |
207 | SRAND(seed); | |
208 | ||
209 | /* | |
210 | * Scratch giants, big enough for anything. Malloc here, init with | |
211 | * random data before each test | |
212 | * note these mallocs will be too big in the useOld case... | |
213 | */ | |
214 | g1 = malloc(sizeof(giant) * loops); | |
215 | g2 = malloc(sizeof(giant) * loops); | |
216 | if((g1 == NULL) || (g2 == NULL)) { | |
217 | printf("malloc error\n"); | |
218 | exit(1); | |
219 | } | |
220 | if(useOld) { | |
221 | numDigits = ((2 * maxSize) + 1) / 2; | |
222 | } | |
223 | else { | |
224 | numDigits = BYTES_TO_GIANT_DIGITS(2 * maxSize); | |
225 | } | |
226 | for(i=0; i<loops; i++) { | |
227 | g1[i] = newGiant(numDigits); | |
228 | g2[i] = newGiant(numDigits); | |
229 | if((g1[i] == NULL) || (g2[i] == NULL)) { | |
230 | printf("malloc error\n"); | |
231 | exit(1); | |
232 | } | |
233 | } | |
234 | ||
235 | printf("Starting giants test: seed %d\n", seed); | |
236 | for(numBytes=minSize; numBytes<=maxSize; numBytes*=2) { | |
237 | ||
238 | initRandGiants(numBytes, | |
239 | buf, | |
240 | loops, | |
241 | g1, | |
242 | g2); | |
243 | ||
244 | mulgElapsed = mulgTest(loops, g1, g2); | |
245 | initRandGiants(numBytes, | |
246 | buf, | |
247 | loops, | |
248 | g1, | |
249 | g2); | |
250 | ||
251 | sqrElapsed = squareTest(loops, g1, g2); | |
252 | printf(" bits : %4d mulg : %3d ns gsquare : %3d ns\n", | |
253 | numBytes * 8, | |
254 | mulgElapsed / loops, | |
255 | sqrElapsed / loops); | |
256 | ||
257 | } /* for numBytes */ | |
258 | return 0; | |
259 | } |