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

Last change on this file since 911 was 911, checked in by sam, 12 years ago

test: add a few Visual Studio 2010 project files and fix testsuite code
so that it builds properly.

  • Property svn:keywords set to Id
File size: 11.8 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#ifdef WIN32
16#   define _USE_MATH_DEFINES /* for M_PI */
17#   define WIN32_LEAN_AND_MEAN
18#   include <windows.h>
19#endif
20
21#include <cstdio>
22
23#if defined HAVE_FASTMATH_H
24#   include <fastmath.h>
25#endif
26
27#include "core.h"
28#include "loldebug.h"
29
30using namespace std;
31using namespace lol;
32
33static size_t const TRIG_TABLE_SIZE = 128 * 1024;
34static size_t const TRIG_RUNS = 50;
35
36static size_t const MATRIX_TABLE_SIZE = 64 * 1024;
37static size_t const MATRIX_RUNS = 100;
38
39static size_t const HALF_TABLE_SIZE = 1024 * 1024;
40static size_t const HALF_RUNS = 50;
41
42static void bench_trig(int mode);
43static void bench_matrix(int mode);
44static void bench_half(int mode);
45
46int main(int argc, char **argv)
47{
48    Log::Info("--------------------------\n");
49    Log::Info(" Trigonometry [-1e5, 1e5]\n");
50    Log::Info("--------------------------\n");
51    bench_trig(1);
52
53    Log::Info("------------------------\n");
54    Log::Info(" Trigonometry [-pi, pi]\n");
55    Log::Info("------------------------\n");
56    bench_trig(2);
57
58    Log::Info("----------------------------\n");
59    Log::Info(" Trigonometry [-1e-2, 1e-2]\n");
60    Log::Info("----------------------------\n");
61    bench_trig(3);
62
63    Log::Info("----------------------------\n");
64    Log::Info(" Float matrices [-2.0, 2.0]\n");
65    Log::Info("----------------------------\n");
66    bench_matrix(1);
67
68    Log::Info("-------------------------------------\n");
69    Log::Info(" Half precision floats (random bits)\n");
70    Log::Info("-------------------------------------\n");
71    bench_half(1);
72
73    Log::Info("-----------------------------------\n");
74    Log::Info(" Half precision floats [-2.0, 2.0]\n");
75    Log::Info("-----------------------------------\n");
76    bench_half(2);
77
78#if defined _WIN32
79    getchar();
80#endif
81
82    return EXIT_SUCCESS;
83}
84
85static void bench_trig(int mode)
86{
87    float result[12] = { 0.0f };
88    Timer timer;
89
90    /* Set up tables */
91    float *pf = new float[TRIG_TABLE_SIZE];
92    float *pf2 = new float[TRIG_TABLE_SIZE];
93    float *pf3 = new float[TRIG_TABLE_SIZE];
94
95    for (size_t run = 0; run < TRIG_RUNS; run++)
96    {
97        switch (mode)
98        {
99        case 1:
100            for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
101                pf[i] = RandF(-1e5f, 1e5f);
102            break;
103        case 2:
104            for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
105                pf[i] = RandF(-M_PI, M_PI);
106            break;
107        case 3:
108            for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
109                pf[i] = RandF(-1e-2f, 1e-2f);
110            break;
111        }
112
113        /* Sin */
114        timer.GetMs();
115        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
116#if defined __GNUC__
117            pf2[i] = __builtin_sinf(pf[i]);
118#else
119            pf2[i] = sinf(pf[i]);
120#endif
121        result[0] += timer.GetMs();
122
123        /* Fast sin */
124        timer.GetMs();
125        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
126#if defined HAVE_FASTMATH_H
127            pf2[i] = f_sinf(pf[i]);
128#else
129            pf2[i] = sinf(pf[i]);
130#endif
131        result[1] += timer.GetMs();
132
133        /* Lol sin */
134        timer.GetMs();
135        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
136            pf2[i] = lol_sin(pf[i]);
137        result[2] += timer.GetMs();
138
139        /* Cos */
140        timer.GetMs();
141        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
142#if defined __GNUC__
143            pf2[i] = __builtin_cosf(pf[i]);
144#else
145            pf2[i] = cosf(pf[i]);
146#endif
147        result[3] += timer.GetMs();
148
149        /* Fast cos */
150        timer.GetMs();
151        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
152#if defined HAVE_FASTMATH_H
153            pf2[i] = f_cosf(pf[i]);
154#else
155            pf2[i] = cosf(pf[i]);
156#endif
157        result[4] += timer.GetMs();
158
159        /* Lol cos */
160        timer.GetMs();
161        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
162            pf2[i] = lol_cos(pf[i]);
163        result[5] += timer.GetMs();
164
165        /* Sin & cos */
166        timer.GetMs();
167        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
168        {
169#if defined __GNUC__
170            pf2[i] = __builtin_sinf(pf[i]);
171            pf3[i] = __builtin_cosf(pf[i]);
172#else
173            pf2[i] = sinf(pf[i]);
174            pf3[i] = cosf(pf[i]);
175#endif
176        }
177        result[6] += timer.GetMs();
178
179        /* Fast sin & cos */
180        timer.GetMs();
181        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
182        {
183#if defined HAVE_FASTMATH_H
184            pf2[i] = f_sinf(pf[i]);
185            pf3[i] = f_cosf(pf[i]);
186#else
187            pf2[i] = sinf(pf[i]);
188            pf3[i] = cosf(pf[i]);
189#endif
190        }
191        result[7] += timer.GetMs();
192
193        /* Lol sincos */
194        timer.GetMs();
195        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
196            lol_sincos(pf[i], &pf2[i], &pf3[i]);
197        result[8] += timer.GetMs();
198
199        /* Tan */
200        timer.GetMs();
201        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
202#if defined __GNUC__
203            pf2[i] = __builtin_tanf(pf[i]);
204#else
205            pf2[i] = tanf(pf[i]);
206#endif
207        result[9] += timer.GetMs();
208
209        /* Fast tan */
210        timer.GetMs();
211        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
212#if defined HAVE_FASTMATH_H
213            pf2[i] = f_tanf(pf[i]);
214#else
215            pf2[i] = tanf(pf[i]);
216#endif
217        result[10] += timer.GetMs();
218
219        /* Lol tan */
220        timer.GetMs();
221        for (size_t i = 0; i < TRIG_TABLE_SIZE; i++)
222            pf2[i] = lol_tan(pf[i]);
223        result[11] += timer.GetMs();
224    }
225
226    delete[] pf;
227    delete[] pf2;
228    delete[] pf3;
229
230    for (size_t i = 0; i < sizeof(result) / sizeof(*result); i++)
231        result[i] *= 1000000.0f / (TRIG_TABLE_SIZE * TRIG_RUNS);
232
233    Log::Info("                              ns/elem\n");
234    Log::Info("float = sinf(float)          %7.3f\n", result[0]);
235    Log::Info("float = f_sinf(float)        %7.3f\n", result[1]);
236    Log::Info("float = lol_sin(float)       %7.3f\n", result[2]);
237    Log::Info("float = cosf(float)          %7.3f\n", result[3]);
238    Log::Info("float = f_cosf(float)        %7.3f\n", result[4]);
239    Log::Info("float = lol_cos(float)       %7.3f\n", result[5]);
240    Log::Info("float = sinf,cosf(float)     %7.3f\n", result[6]);
241    Log::Info("float = f_sinf,f_cosf(float) %7.3f\n", result[7]);
242    Log::Info("float = lol_sincos(float)    %7.3f\n", result[8]);
243    Log::Info("float = tanf(float)          %7.3f\n", result[9]);
244    Log::Info("float = f_tanf(float)        %7.3f\n", result[10]);
245    Log::Info("float = lol_tanf(float)      %7.3f\n", result[11]);
246}
247
248static void bench_matrix(int mode)
249{
250    float result[5] = { 0.0f };
251    Timer timer;
252
253    /* Set up tables */
254    mat4 *pm = new mat4[MATRIX_TABLE_SIZE + 1];
255    float *pf = new float[MATRIX_TABLE_SIZE];
256
257    for (size_t run = 0; run < MATRIX_RUNS; run++)
258    {
259        switch (mode)
260        {
261        case 1:
262            for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
263                for (int j = 0; j < 4; j++)
264                    for (int k = 0; k < 4; k++)
265                        pm[i][j][k] = RandF(-2.0f, 2.0f);
266            break;
267        }
268
269        /* Copy matrices */
270        timer.GetMs();
271        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
272            pm[i] = pm[i + 1];
273        result[0] += timer.GetMs();
274
275        /* Determinant */
276        timer.GetMs();
277        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
278            pf[i] = pm[i].det();
279        result[1] += timer.GetMs();
280
281        /* Multiply matrices */
282        timer.GetMs();
283        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
284            pm[i] *= pm[i + 1];
285        result[2] += timer.GetMs();
286
287        /* Add matrices */
288        timer.GetMs();
289        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
290            pm[i] += pm[i + 1];
291        result[3] += timer.GetMs();
292
293        /* Invert matrix */
294        timer.GetMs();
295        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
296            pm[i] = pm[i].invert();
297        result[4] += timer.GetMs();
298    }
299
300    delete[] pm;
301    delete[] pf;
302
303    for (size_t i = 0; i < sizeof(result) / sizeof(*result); i++)
304        result[i] *= 1000000.0f / (MATRIX_TABLE_SIZE * MATRIX_RUNS);
305
306    Log::Info("                          ns/elem\n");
307    Log::Info("mat4 = mat4              %7.3f\n", result[0]);
308    Log::Info("float = mat4.det()       %7.3f\n", result[1]);
309    Log::Info("mat4 *= mat4             %7.3f\n", result[2]);
310    Log::Info("mat4 += mat4             %7.3f\n", result[3]);
311    Log::Info("mat4 = mat4.invert()     %7.3f\n", result[4]);
312}
313
314static void bench_half(int mode)
315{
316    float result[10] = { 0.0f };
317    Timer timer;
318
319    /* Set up tables */
320    float *pf = new float[HALF_TABLE_SIZE + 1];
321    half *ph = new half[HALF_TABLE_SIZE + 1];
322
323    for (size_t run = 0; run < HALF_RUNS; run++)
324    {
325        switch (mode)
326        {
327        case 1:
328            for (size_t i = 0; i < HALF_TABLE_SIZE + 1; i++)
329                ph[i] = half::makebits(rand());
330            break;
331        case 2:
332            for (size_t i = 0; i < HALF_TABLE_SIZE + 1; i++)
333                ph[i] = RandF(-2.0f, 2.0f);
334            break;
335        }
336
337        /* Copy float */
338        timer.GetMs();
339        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
340            pf[i] = pf[i + 1];
341        result[0] += timer.GetMs();
342
343        /* Convert half to float (array) */
344        timer.GetMs();
345        half::convert(pf, ph, HALF_TABLE_SIZE);
346        result[1] += timer.GetMs();
347
348        /* Convert half to float (fast) */
349        timer.GetMs();
350        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
351            pf[i] = (float)ph[i];
352        result[2] += timer.GetMs();
353
354        /* Add a half to every float */
355        timer.GetMs();
356        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
357            pf[i] += ph[i];
358        result[3] += timer.GetMs();
359
360        /* Copy half */
361        timer.GetMs();
362        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
363            ph[i] = ph[i + 1];
364        result[4] += timer.GetMs();
365
366        /* Change sign of every half */
367        timer.GetMs();
368        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
369            ph[i] = -ph[i];
370        result[5] += timer.GetMs();
371
372        /* Convert float to half (array) */
373        timer.GetMs();
374        half::convert(ph, pf, HALF_TABLE_SIZE);
375        result[6] += timer.GetMs();
376
377        /* Convert float to half (fast) */
378        timer.GetMs();
379        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
380            ph[i] = (half)pf[i];
381        result[7] += timer.GetMs();
382
383        /* Convert float to half (accurate) */
384        timer.GetMs();
385        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
386            ph[i] = half::makeaccurate(pf[i]);
387        result[8] += timer.GetMs();
388
389        /* Add a float to every half */
390        timer.GetMs();
391        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
392            ph[i] += pf[i];
393        result[9] += timer.GetMs();
394    }
395
396    delete[] pf;
397    delete[] ph;
398
399    for (size_t i = 0; i < sizeof(result) / sizeof(*result); i++)
400        result[i] *= 1000000.0f / (HALF_TABLE_SIZE * HALF_RUNS);
401
402    Log::Info("                          ns/elem\n");
403    Log::Info("float = float            %7.3f\n", result[0]);
404    Log::Info("float = half (array)     %7.3f\n", result[1]);
405    Log::Info("float = half (fast)      %7.3f\n", result[2]);
406    Log::Info("float += half            %7.3f\n", result[3]);
407    Log::Info("half = half              %7.3f\n", result[4]);
408    Log::Info("half = -half             %7.3f\n", result[5]);
409    Log::Info("half = float (array)     %7.3f\n", result[6]);
410    Log::Info("half = float (fast)      %7.3f\n", result[7]);
411    Log::Info("half = float (accurate)  %7.3f\n", result[8]);
412    Log::Info("half += float            %7.3f\n", result[9]);
413}
414
Note: See TracBrowser for help on using the repository browser.