diff options
Diffstat (limited to 'nacl/measure-anything.c')
-rw-r--r-- | nacl/measure-anything.c | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/nacl/measure-anything.c b/nacl/measure-anything.c new file mode 100644 index 00000000..32555060 --- /dev/null +++ b/nacl/measure-anything.c | |||
@@ -0,0 +1,225 @@ | |||
1 | /* | ||
2 | * measure-anything.c version 20090223 | ||
3 | * D. J. Bernstein | ||
4 | * Public domain. | ||
5 | */ | ||
6 | |||
7 | #include <stdio.h> | ||
8 | #include <stdlib.h> | ||
9 | #include <string.h> | ||
10 | #include <time.h> | ||
11 | #include <sys/time.h> | ||
12 | #include <sys/types.h> | ||
13 | #include <sys/resource.h> | ||
14 | #include "cpucycles.h" | ||
15 | #include "cpuid.h" | ||
16 | |||
17 | typedef int uint32; | ||
18 | |||
19 | static uint32 seed[32] = { 3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3,3,8,3,2,7,9,5 } ; | ||
20 | static uint32 in[12]; | ||
21 | static uint32 out[8]; | ||
22 | static int outleft = 0; | ||
23 | |||
24 | #define ROTATE(x,b) (((x) << (b)) | ((x) >> (32 - (b)))) | ||
25 | #define MUSH(i,b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x,b)); | ||
26 | |||
27 | static void surf(void) | ||
28 | { | ||
29 | uint32 t[12]; uint32 x; uint32 sum = 0; | ||
30 | int r; int i; int loop; | ||
31 | |||
32 | for (i = 0;i < 12;++i) t[i] = in[i] ^ seed[12 + i]; | ||
33 | for (i = 0;i < 8;++i) out[i] = seed[24 + i]; | ||
34 | x = t[11]; | ||
35 | for (loop = 0;loop < 2;++loop) { | ||
36 | for (r = 0;r < 16;++r) { | ||
37 | sum += 0x9e3779b9; | ||
38 | MUSH(0,5) MUSH(1,7) MUSH(2,9) MUSH(3,13) | ||
39 | MUSH(4,5) MUSH(5,7) MUSH(6,9) MUSH(7,13) | ||
40 | MUSH(8,5) MUSH(9,7) MUSH(10,9) MUSH(11,13) | ||
41 | } | ||
42 | for (i = 0;i < 8;++i) out[i] ^= t[i + 4]; | ||
43 | } | ||
44 | } | ||
45 | |||
46 | void randombytes(unsigned char *x,unsigned long long xlen) | ||
47 | { | ||
48 | while (xlen > 0) { | ||
49 | if (!outleft) { | ||
50 | if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3]; | ||
51 | surf(); | ||
52 | outleft = 8; | ||
53 | } | ||
54 | *x = out[--outleft]; | ||
55 | ++x; | ||
56 | --xlen; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | extern const char *primitiveimplementation; | ||
61 | extern const char *implementationversion; | ||
62 | extern const char *sizenames[]; | ||
63 | extern const long long sizes[]; | ||
64 | extern void preallocate(void); | ||
65 | extern void allocate(void); | ||
66 | extern void measure(void); | ||
67 | |||
68 | static void printword(const char *s) | ||
69 | { | ||
70 | if (!*s) putchar('-'); | ||
71 | while (*s) { | ||
72 | if (*s == ' ') putchar('_'); | ||
73 | else if (*s == '\t') putchar('_'); | ||
74 | else if (*s == '\r') putchar('_'); | ||
75 | else if (*s == '\n') putchar('_'); | ||
76 | else putchar(*s); | ||
77 | ++s; | ||
78 | } | ||
79 | putchar(' '); | ||
80 | } | ||
81 | |||
82 | static void printnum(long long x) | ||
83 | { | ||
84 | printf("%lld ",x); | ||
85 | } | ||
86 | |||
87 | static void fail(const char *why) | ||
88 | { | ||
89 | fprintf(stderr,"measure: fatal: %s\n",why); | ||
90 | exit(111); | ||
91 | } | ||
92 | |||
93 | unsigned char *alignedcalloc(unsigned long long len) | ||
94 | { | ||
95 | unsigned char *x = (unsigned char *) calloc(1,len + 128); | ||
96 | if (!x) fail("out of memory"); | ||
97 | /* will never deallocate so shifting is ok */ | ||
98 | x += 63 & (-(unsigned long) x); | ||
99 | return x; | ||
100 | } | ||
101 | |||
102 | static long long cyclespersecond; | ||
103 | |||
104 | static void printimplementations(void) | ||
105 | { | ||
106 | int i; | ||
107 | |||
108 | printword("implementation"); | ||
109 | printword(primitiveimplementation); | ||
110 | printword(implementationversion); | ||
111 | printf("\n"); fflush(stdout); | ||
112 | |||
113 | for (i = 0;sizenames[i];++i) { | ||
114 | printword(sizenames[i]); | ||
115 | printnum(sizes[i]); | ||
116 | printf("\n"); fflush(stdout); | ||
117 | } | ||
118 | |||
119 | printword("cpuid"); | ||
120 | printword(cpuid); | ||
121 | printf("\n"); fflush(stdout); | ||
122 | |||
123 | printword("cpucycles_persecond"); | ||
124 | printnum(cyclespersecond); | ||
125 | printf("\n"); fflush(stdout); | ||
126 | |||
127 | printword("cpucycles_implementation"); | ||
128 | printword(cpucycles_implementation); | ||
129 | printf("\n"); fflush(stdout); | ||
130 | |||
131 | printword("compiler"); | ||
132 | printword(COMPILER); | ||
133 | #if defined(__VERSION__) && !defined(__ICC) | ||
134 | printword(__VERSION__); | ||
135 | #elif defined(__xlc__) | ||
136 | printword(__xlc__); | ||
137 | #elif defined(__ICC) | ||
138 | { | ||
139 | char buf[256]; | ||
140 | |||
141 | sprintf(buf, "%d.%d.%d", __ICC/100, __ICC%100, | ||
142 | __INTEL_COMPILER_BUILD_DATE); | ||
143 | printword(buf); | ||
144 | } | ||
145 | #elif defined(__PGIC__) | ||
146 | { | ||
147 | char buf[256]; | ||
148 | |||
149 | sprintf(buf, "%d.%d.%d", __PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__); | ||
150 | printword(buf); | ||
151 | } | ||
152 | #elif defined(__SUNPRO_C) | ||
153 | { | ||
154 | char buf[256]; | ||
155 | int major, minor, micro; | ||
156 | |||
157 | micro = __SUNPRO_C & 0xf; | ||
158 | minor = (__SUNPRO_C >> 4) & 0xf; | ||
159 | major = (__SUNPRO_C >> 8) & 0xf; | ||
160 | |||
161 | if (micro) | ||
162 | sprintf(buf, "%d.%d.%d", major, minor, micro); | ||
163 | else | ||
164 | sprintf(buf, "%d.%d", major, minor); | ||
165 | printword(buf); | ||
166 | } | ||
167 | #else | ||
168 | printword("unknown compiler version"); | ||
169 | #endif | ||
170 | printf("\n"); fflush(stdout); | ||
171 | } | ||
172 | |||
173 | void printentry(long long mbytes,const char *measuring,long long *m,long long mlen) | ||
174 | { | ||
175 | long long i; | ||
176 | long long j; | ||
177 | long long belowj; | ||
178 | long long abovej; | ||
179 | |||
180 | printword(measuring); | ||
181 | if (mbytes >= 0) printnum(mbytes); else printword(""); | ||
182 | if (mlen > 0) { | ||
183 | for (j = 0;j + 1 < mlen;++j) { | ||
184 | belowj = 0; | ||
185 | for (i = 0;i < mlen;++i) if (m[i] < m[j]) ++belowj; | ||
186 | abovej = 0; | ||
187 | for (i = 0;i < mlen;++i) if (m[i] > m[j]) ++abovej; | ||
188 | if (belowj * 2 < mlen && abovej * 2 < mlen) break; | ||
189 | } | ||
190 | printnum(m[j]); | ||
191 | if (mlen > 1) { | ||
192 | for (i = 0;i < mlen;++i) printnum(m[i]); | ||
193 | } | ||
194 | } | ||
195 | printf("\n"); fflush(stdout); | ||
196 | } | ||
197 | |||
198 | void limits() | ||
199 | { | ||
200 | #ifdef RLIM_INFINITY | ||
201 | struct rlimit r; | ||
202 | r.rlim_cur = 0; | ||
203 | r.rlim_max = 0; | ||
204 | #ifdef RLIMIT_NOFILE | ||
205 | setrlimit(RLIMIT_NOFILE,&r); | ||
206 | #endif | ||
207 | #ifdef RLIMIT_NPROC | ||
208 | setrlimit(RLIMIT_NPROC,&r); | ||
209 | #endif | ||
210 | #ifdef RLIMIT_CORE | ||
211 | setrlimit(RLIMIT_CORE,&r); | ||
212 | #endif | ||
213 | #endif | ||
214 | } | ||
215 | |||
216 | int main() | ||
217 | { | ||
218 | cyclespersecond = cpucycles_persecond(); | ||
219 | preallocate(); | ||
220 | limits(); | ||
221 | printimplementations(); | ||
222 | allocate(); | ||
223 | measure(); | ||
224 | return 0; | ||
225 | } | ||