source: trunk/test/lol-bench.cpp @ 897

Last change on this file since 897 was 897, checked in by sam, 8 years ago

core: implement accelerated cos().

  • Property svn:keywords set to Id
File size: 9.7 KB
Line 
1//
2// Lol Engine - Benchmark program
3//
4// Copyright: (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <cstdio>
16
17#if defined HAVE_FASTMATH_H
18#   include <fastmath.h>
19#endif
20
21#include "core.h"
22#include "loldebug.h"
23
24using namespace std;
25using namespace lol;
26
27static size_t const TRIG_TABLE_SIZE = 128 * 1024;
28static size_t const TRIG_RUNS = 50;
29
30static size_t const MATRIX_TABLE_SIZE = 64 * 1024;
31static size_t const MATRIX_RUNS = 100;
32
33static size_t const HALF_TABLE_SIZE = 1024 * 1024;
34static size_t const HALF_RUNS = 50;
35
36static void bench_trig(int mode);
37static void bench_matrix(int mode);
38static void bench_half(int mode);
39
40int main(int argc, char **argv)
41{
42    Log::Info("--------------------------\n");
43    Log::Info(" Trigonometry [-1e5, 1e5]\n");
44    Log::Info("--------------------------\n");
45    bench_trig(1);
46
47    Log::Info("------------------------\n");
48    Log::Info(" Trigonometry [-pi, pi]\n");
49    Log::Info("------------------------\n");
50    bench_trig(2);
51
52    Log::Info("----------------------------\n");
53    Log::Info(" Trigonometry [-1e-2, 1e-2]\n");
54    Log::Info("----------------------------\n");
55    bench_trig(3);
56
57    Log::Info("----------------------------\n");
58    Log::Info(" Float matrices [-2.0, 2.0]\n");
59    Log::Info("----------------------------\n");
60    bench_matrix(1);
61
62    Log::Info("-------------------------------------\n");
63    Log::Info(" Half precision floats (random bits)\n");
64    Log::Info("-------------------------------------\n");
65    bench_half(1);
66
67    Log::Info("-----------------------------------\n");
68    Log::Info(" Half precision floats [-2.0, 2.0]\n");
69    Log::Info("-----------------------------------\n");
70    bench_half(2);
71
72    return EXIT_SUCCESS;
73}
74
75static void bench_trig(int mode)
76{
77    float result[7] = { 0.0f };
78    Timer timer;
79
80    /* Set up tables */
81    float *pf = new float[TRIG_TABLE_SIZE];
82    float *pf2 = new float[TRIG_TABLE_SIZE];
83
84    for (size_t run = 0; run < TRIG_RUNS; run++)
85    {
86        switch (mode)
87        {
88        case 1:
89            for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
90                pf[i] = RandF(-1e5f, 1e5f);
91            break;
92        case 2:
93            for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
94                pf[i] = RandF(-M_PI, M_PI);
95            break;
96        case 3:
97            for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
98                pf[i] = RandF(-1e-2f, 1e-2f);
99            break;
100        }
101
102        /* Sin */
103        timer.GetMs();
104        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
105            pf2[i] = __builtin_sinf(pf[i]);
106        result[0] += timer.GetMs();
107
108        /* Fast sin */
109        timer.GetMs();
110        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
111#if defined HAVE_FASTMATH_H
112            pf2[i] = f_sinf(pf[i]);
113#else
114            pf2[i] = sinf(pf[i]);
115#endif
116        result[1] += timer.GetMs();
117
118        /* Lol sin */
119        timer.GetMs();
120        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
121            pf2[i] = lol_sin(pf[i]);
122        result[2] += timer.GetMs();
123
124        /* Cos */
125        timer.GetMs();
126        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
127            pf2[i] = __builtin_cosf(pf[i]);
128        result[3] += timer.GetMs();
129
130        /* Fast cos */
131        timer.GetMs();
132        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
133#if defined HAVE_FASTMATH_H
134            pf2[i] = f_cosf(pf[i]);
135#else
136            pf2[i] = cosf(pf[i]);
137#endif
138        result[4] += timer.GetMs();
139
140        /* Lol cos */
141        timer.GetMs();
142        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
143            pf2[i] = lol_cos(pf[i]);
144        result[5] += timer.GetMs();
145
146        /* Tan */
147        timer.GetMs();
148        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
149            pf2[i] = __builtin_tanf(pf[i]);
150        result[6] += timer.GetMs();
151    }
152
153    delete[] pf;
154    delete[] pf2;
155
156    for (size_t i = 0; i < sizeof(result) / sizeof(*result); i++)
157        result[i] *= 1000000.0f / (TRIG_TABLE_SIZE * TRIG_RUNS);
158
159    Log::Info("                          ns/elem\n");
160    Log::Info("float = sinf(float)      %7.3f\n", result[0]);
161    Log::Info("float = fastsinf(float)  %7.3f\n", result[1]);
162    Log::Info("float = lol_sinf(float)  %7.3f\n", result[2]);
163    Log::Info("float = cosf(float)      %7.3f\n", result[3]);
164    Log::Info("float = fastcosf(float)  %7.3f\n", result[4]);
165    Log::Info("float = lol_cosf(float)  %7.3f\n", result[5]);
166    Log::Info("float = tanf(float)      %7.3f\n", result[6]);
167}
168
169static void bench_matrix(int mode)
170{
171    float result[5] = { 0.0f };
172    Timer timer;
173
174    /* Set up tables */
175    mat4 *pm = new mat4[MATRIX_TABLE_SIZE + 1];
176    float *pf = new float[MATRIX_TABLE_SIZE];
177
178    for (size_t run = 0; run < MATRIX_RUNS; run++)
179    {
180        switch (mode)
181        {
182        case 1:
183            for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
184                for (int j = 0; j < 4; j++)
185                    for (int k = 0; k < 4; k++)
186                        pm[i][j][k] = RandF(-2.0f, 2.0f);
187            break;
188        }
189
190        /* Copy matrices */
191        timer.GetMs();
192        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
193            pm[i] = pm[i + 1];
194        result[0] += timer.GetMs();
195
196        /* Determinant */
197        timer.GetMs();
198        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
199            pf[i] = pm[i].det();
200        result[1] += timer.GetMs();
201
202        /* Multiply matrices */
203        timer.GetMs();
204        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
205            pm[i] *= pm[i + 1];
206        result[2] += timer.GetMs();
207
208        /* Add matrices */
209        timer.GetMs();
210        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
211            pm[i] += pm[i + 1];
212        result[3] += timer.GetMs();
213
214        /* Invert matrix */
215        timer.GetMs();
216        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
217            pm[i] = pm[i].invert();
218        result[4] += timer.GetMs();
219    }
220
221    delete[] pm;
222    delete[] pf;
223
224    for (size_t i = 0; i < sizeof(result) / sizeof(*result); i++)
225        result[i] *= 1000000.0f / (MATRIX_TABLE_SIZE * MATRIX_RUNS);
226
227    Log::Info("                          ns/elem\n");
228    Log::Info("mat4 = mat4              %7.3f\n", result[0]);
229    Log::Info("float = mat4.det()       %7.3f\n", result[1]);
230    Log::Info("mat4 *= mat4             %7.3f\n", result[2]);
231    Log::Info("mat4 += mat4             %7.3f\n", result[3]);
232    Log::Info("mat4 = mat4.invert()     %7.3f\n", result[4]);
233}
234
235static void bench_half(int mode)
236{
237    float result[10] = { 0.0f };
238    Timer timer;
239
240    /* Set up tables */
241    float *pf = new float[HALF_TABLE_SIZE + 1];
242    half *ph = new half[HALF_TABLE_SIZE + 1];
243
244    for (size_t run = 0; run < HALF_RUNS; run++)
245    {
246        switch (mode)
247        {
248        case 1:
249            for (size_t i = 0; i < HALF_TABLE_SIZE + 1; i++)
250                ph[i] = half::makebits(rand());
251            break;
252        case 2:
253            for (size_t i = 0; i < HALF_TABLE_SIZE + 1; i++)
254                ph[i] = RandF(-2.0f, 2.0f);
255            break;
256        }
257
258        /* Copy float */
259        timer.GetMs();
260        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
261            pf[i] = pf[i + 1];
262        result[0] += timer.GetMs();
263
264        /* Convert half to float (array) */
265        timer.GetMs();
266        half::convert(pf, ph, HALF_TABLE_SIZE);
267        result[1] += timer.GetMs();
268
269        /* Convert half to float (fast) */
270        timer.GetMs();
271        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
272            pf[i] = (float)ph[i];
273        result[2] += timer.GetMs();
274
275        /* Add a half to every float */
276        timer.GetMs();
277        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
278            pf[i] += ph[i];
279        result[3] += timer.GetMs();
280
281        /* Copy half */
282        timer.GetMs();
283        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
284            ph[i] = ph[i + 1];
285        result[4] += timer.GetMs();
286
287        /* Change sign of every half */
288        timer.GetMs();
289        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
290            ph[i] = -ph[i];
291        result[5] += timer.GetMs();
292
293        /* Convert float to half (array) */
294        timer.GetMs();
295        half::convert(ph, pf, HALF_TABLE_SIZE);
296        result[6] += timer.GetMs();
297
298        /* Convert float to half (fast) */
299        timer.GetMs();
300        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
301            ph[i] = (half)pf[i];
302        result[7] += timer.GetMs();
303
304        /* Convert float to half (accurate) */
305        timer.GetMs();
306        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
307            ph[i] = half::makeaccurate(pf[i]);
308        result[8] += timer.GetMs();
309
310        /* Add a float to every half */
311        timer.GetMs();
312        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
313            ph[i] += pf[i];
314        result[9] += timer.GetMs();
315    }
316
317    delete[] pf;
318    delete[] ph;
319
320    for (size_t i = 0; i < sizeof(result) / sizeof(*result); i++)
321        result[i] *= 1000000.0f / (HALF_TABLE_SIZE * HALF_RUNS);
322
323    Log::Info("                          ns/elem\n");
324    Log::Info("float = float            %7.3f\n", result[0]);
325    Log::Info("float = half (array)     %7.3f\n", result[1]);
326    Log::Info("float = half (fast)      %7.3f\n", result[2]);
327    Log::Info("float += half            %7.3f\n", result[3]);
328    Log::Info("half = half              %7.3f\n", result[4]);
329    Log::Info("half = -half             %7.3f\n", result[5]);
330    Log::Info("half = float (array)     %7.3f\n", result[6]);
331    Log::Info("half = float (fast)      %7.3f\n", result[7]);
332    Log::Info("half = float (accurate)  %7.3f\n", result[8]);
333    Log::Info("half += float            %7.3f\n", result[9]);
334}
335
Note: See TracBrowser for help on using the repository browser.