ulps: Fix long lines
[mathlib.git] / etc / proffenv.c
1 #include <assert.h>
2 #include <fenv.h>
3 #include <stdio.h>
4 #include <time.h>
5 #include <sys/time.h>
6
7 /* Function prototypes */
8 static int prof_clearexcept_all(size_t iterations);
9 static int prof_clearexcept_random(size_t iterations);
10 static int prof_getenv(size_t iterations);
11 static int prof_getround(size_t iterations);
12 static int prof_holdexcept(size_t iterations);
13 static int prof_raiseexcept(size_t iterations);
14 static int prof_setenv_default(size_t iterations);
15 static int prof_setenv_getenv(size_t iterations);
16 static int prof_setround(size_t iterations);
17 static int prof_updateenv_default(size_t iterations);
18 static int prof_updateenv_getenv(size_t iterations);
19
20
21 /* Constants and macros */
22 #define ITERATIONS (10 * 1000 * 1000)
23
24 /*
25  * They are esentially the same, but we still define them as if
26  * they were different, for conceptual consistency and clarity.
27  */
28 #define MARK_START(tv1)                                 \
29         assert(gettimeofday(tv1, NULL) == 0);
30
31 #define MARK_END(tv2)                                   \
32         assert(gettimeofday(tv2, NULL) == 0);
33
34 #define MSECS(tv1, tv2)                                 \
35         (((tv2).tv_sec  - (tv1).tv_sec ) * 1000 +       \
36          ((tv2).tv_usec - (tv1).tv_usec) / 1000)
37
38 static int extable[] = {
39 #ifdef  FE_DIVBYZERO
40         FE_DIVBYZERO,
41 #endif
42 #ifdef  FE_INEXACT
43         FE_INEXACT,
44 #endif
45 #ifdef  FE_INVALID
46         FE_INVALID,
47 #endif
48 #ifdef  FE_OVERFLOW
49         FE_OVERFLOW,
50 #endif
51 #ifdef  FE_UNDERFLOW
52         FE_UNDERFLOW,
53 #endif
54 #ifdef  FE_ALL_EXCEPT
55         FE_ALL_EXCEPT
56 #endif
57 };
58
59 struct pentry {
60         const char *p_desc;
61         int (*p_func)();
62         size_t p_iter;
63 } ptable[] = {
64         { "feclearexcept() FE_ALL_EXCEPT",
65           prof_clearexcept_all,
66           ITERATIONS },
67
68         { "feclearexcept()        random",
69           prof_clearexcept_random,
70           ITERATIONS },
71
72         { "     fegetenv()              ",
73           prof_getenv,
74           ITERATIONS },
75
76         { "   fegetround()              ",
77           prof_getround,
78           ITERATIONS },
79
80         { " feholdexcept()              ",
81           prof_holdexcept,
82           ITERATIONS },
83
84         { "feraiseexcept()              ",
85           prof_raiseexcept,
86           ITERATIONS },
87
88         { "     fesetenv()    FE_DFL_ENV",
89           prof_setenv_default,
90           ITERATIONS },
91
92         { "     fesetenv()        random",
93           prof_setenv_getenv,
94           ITERATIONS },
95
96         { "   fesetround()              ",
97           prof_setround,
98           ITERATIONS },
99
100         { "  feupdateenv()    FE_DFL_ENV",
101           prof_updateenv_default,
102           ITERATIONS },
103
104         { "  feupdateenv()        random",
105           prof_updateenv_getenv,
106           ITERATIONS },
107
108         { NULL, NULL, 0 }
109 };
110
111 int
112 main(void)
113 {
114         const struct pentry *p;
115         int msecs;
116
117         for (p = ptable; p; p++) {
118                 if (p->p_desc == NULL && p->p_func == NULL && p->p_iter == 0)
119                         break;
120
121                 msecs = p->p_func(p->p_iter);
122                 printf("%s: %5d msecs for %d iterations\n",
123                        p->p_desc, msecs, p->p_iter);
124         }
125
126         return 0;
127 }
128
129 static int
130 prof_clearexcept_all(size_t iterations)
131 {
132         struct timeval tv1, tv2;
133         size_t i;
134
135         MARK_START(&tv1);
136
137         for (i = 0; i < iterations; i++)
138                 assert(feclearexcept(FE_ALL_EXCEPT) == 0);
139
140         MARK_END(&tv2);
141
142         return MSECS(tv1, tv2);
143 }
144
145 static int
146 prof_clearexcept_random(size_t iterations)
147 {
148         struct timeval tv1, tv2;
149         size_t i, N;
150
151         N = sizeof(extable) / sizeof(extable[0]);
152         assert(N != 0);
153
154         MARK_START(&tv1);
155
156         for (i = 0; i < iterations; i++)
157                 assert(feclearexcept(extable[i%N]) == 0);
158
159         MARK_END(&tv2);
160
161         return MSECS(tv1, tv2);
162 }
163
164 static int
165 prof_getenv(size_t iterations)
166 {
167         struct timeval tv1, tv2;
168         fenv_t env;
169         size_t i;
170
171         MARK_START(&tv1);
172
173         for (i = 0; i < iterations; i++)
174                 assert(fegetenv(&env) == 0);
175
176         MARK_END(&tv2);
177
178         return MSECS(tv1, tv2);
179 }
180
181 static int
182 prof_getround(size_t iterations)
183 {
184         struct timeval tv1, tv2;
185         size_t i;
186
187         MARK_START(&tv1);
188
189         for (i = 0; i < iterations; i++)
190                 assert(fegetround() == 0);
191
192         MARK_END(&tv2);
193
194         return MSECS(tv1, tv2);
195 }
196
197 static int
198 prof_holdexcept(size_t iterations)
199 {
200         struct timeval tv1, tv2;
201         fenv_t env;
202         size_t i;
203
204         MARK_START(&tv1);
205
206         for (i = 0; i < iterations; i++)
207                 assert(feholdexcept(&env) == 0);
208
209         MARK_END(&tv2);
210
211         return MSECS(tv1, tv2);
212 }
213
214 static int
215 prof_setenv_default(size_t iterations)
216 {
217         struct timeval tv1, tv2;
218         size_t i;
219
220         MARK_START(&tv1);
221
222         for (i = 0; i < iterations; i++)
223                 assert(fesetenv(FE_DFL_ENV) == 0);
224
225         MARK_END(&tv2);
226
227         return MSECS(tv1, tv2);
228 }
229
230 static int
231 prof_updateenv_default(size_t iterations)
232 {
233         struct timeval tv1, tv2;
234         size_t i;
235
236         MARK_START(&tv1);
237
238         for (i = 0; i < iterations; i++)
239                 assert(feupdateenv(FE_DFL_ENV) == 0);
240
241         MARK_END(&tv2);
242
243         return MSECS(tv1, tv2);
244 }
245
246 static int
247 prof_setenv_getenv(size_t iterations)
248 {
249         struct timeval tv1, tv2;
250         fenv_t env;
251         size_t i;
252
253         MARK_START(&tv1);
254
255         for (i = 0; i < iterations; i++) {
256                 assert(fegetenv(&env) == 0);
257                 assert(fesetenv(&env) == 0);
258         }
259
260         MARK_END(&tv2);
261
262         return MSECS(tv1, tv2);
263 }
264
265 static int
266 prof_setround(size_t iterations)
267 {
268         const int rndmodes[] = {
269 #ifdef  FE_DOWNWARD
270         FE_DOWNWARD,
271 #endif
272 #ifdef  FE_TONEAREST
273         FE_TONEAREST,
274 #endif
275 #ifdef  FE_TOWARDZERO
276         FE_TOWARDZERO,
277 #endif
278 #ifdef  FE_UPWARD
279         FE_UPWARD
280 #endif
281         };
282         const size_t N = sizeof(rndmodes) / sizeof(rndmodes[0]);
283         struct timeval tv1, tv2;
284         size_t i;
285
286         MARK_START(&tv1);
287
288         for (i = 0; i < iterations; i++) {
289                 assert(fesetround(rndmodes[i % N]) == 0);
290         }
291
292         MARK_END(&tv2);
293
294         return MSECS(tv1, tv2);
295 }
296
297 static int
298 prof_updateenv_getenv(size_t iterations)
299 {
300         struct timeval tv1, tv2;
301         fenv_t env;
302         size_t i;
303
304         MARK_START(&tv1);
305
306         for (i = 0; i < iterations; i++) {
307                 assert(fegetenv(&env) == 0);
308                 assert(feupdateenv(&env) == 0);
309         }
310
311         MARK_END(&tv2);
312
313         return MSECS(tv1, tv2);
314 }
315
316 static int
317 prof_raiseexcept(size_t iterations)
318 {
319         struct timeval tv1, tv2;
320         size_t i, N;
321
322         N = sizeof(extable) / sizeof(extable[0]);
323         assert(N > 0);
324
325         MARK_START(&tv1);
326
327         for (i = 0; i < iterations; i++) {
328                 assert(feraiseexcept(extable[i%N]) == 0);
329         }
330
331         MARK_END(&tv2);
332
333         return MSECS(tv1, tv2);
334 }