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

Last change on this file since 881 was 881, checked in by sam, 11 years ago

contrib: rebuild the Win32 CppUnit under Linux and fix the includes.

Apparently g++ 4.5.2 on native mingw32 inserts references to Unwind_Resume
when exceptions are supported. This function is not present in the g++ 4.4
cross-compiler found in Debian, leading to linker errors when cross-
compiling. So we use the latter to build CppUnit itself.

Another problem arises with g++ 4.4, which is the incomplete stripping of
exceptions when -fno-exceptions is used. Since ExceptionTestCaseDecorator.h
has such code, we protect it with #ifdef EXCEPTIONS in the meantime.

  • Property svn:keywords set to Id
File size: 6.4 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#include "core.h"
18#include "loldebug.h"
19
20using namespace std;
21using namespace lol;
22
23static size_t const MATRIX_TABLE_SIZE = 64 * 1024;
24static size_t const MATRIX_RUNS = 100;
25
26static size_t const HALF_TABLE_SIZE = 1024 * 1024;
27static size_t const HALF_RUNS = 50;
28
29static void bench_matrix(int mode);
30static void bench_half(int mode);
31
32int main(int argc, char **argv)
33{
34    Log::Info("----------------------------\n");
35    Log::Info(" Float matrices [-2.0, 2.0]\n");
36    Log::Info("----------------------------\n");
37    bench_matrix(1);
38
39    Log::Info("-------------------------------------\n");
40    Log::Info(" Half precision floats (random bits)\n");
41    Log::Info("-------------------------------------\n");
42    bench_half(1);
43
44    Log::Info("-----------------------------------\n");
45    Log::Info(" Half precision floats [-2.0, 2.0]\n");
46    Log::Info("-----------------------------------\n");
47    bench_half(2);
48
49    return EXIT_SUCCESS;
50}
51
52static void bench_matrix(int mode)
53{
54    float result[5] = { 0.0f };
55    Timer timer;
56
57    /* Set up tables */
58    mat4 *pm = new mat4[MATRIX_TABLE_SIZE + 1];
59    float *pf = new float[MATRIX_TABLE_SIZE];
60
61    for (size_t run = 0; run < MATRIX_RUNS; run++)
62    {
63        switch (mode)
64        {
65        case 1:
66            for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
67                for (int j = 0; j < 4; j++)
68                    for (int k = 0; k < 4; k++)
69                        pm[i][j][k] = RandF(-2.0f, 2.0f);
70            break;
71        }
72
73        /* Copy matrices */
74        timer.GetMs();
75        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
76            pm[i] = pm[i + 1];
77        result[0] += timer.GetMs();
78
79        /* Determinant */
80        timer.GetMs();
81        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
82            pf[i] = pm[i].det();
83        result[1] += timer.GetMs();
84
85        /* Multiply matrices */
86        timer.GetMs();
87        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
88            pm[i] *= pm[i + 1];
89        result[2] += timer.GetMs();
90
91        /* Add matrices */
92        timer.GetMs();
93        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
94            pm[i] += pm[i + 1];
95        result[3] += timer.GetMs();
96
97        /* Invert matrix */
98        timer.GetMs();
99        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
100            pm[i] = pm[i].invert();
101        result[4] += timer.GetMs();
102    }
103
104    delete[] pm;
105    delete[] pf;
106
107    for (size_t i = 0; i < sizeof(result) / sizeof(*result); i++)
108        result[i] *= 1000000.0f / (MATRIX_TABLE_SIZE * MATRIX_RUNS);
109
110    Log::Info("                          ns/elem\n");
111    Log::Info("mat4 = mat4              %7.3f\n", result[0]);
112    Log::Info("float = mat4.det()       %7.3f\n", result[1]);
113    Log::Info("mat4 *= mat4             %7.3f\n", result[2]);
114    Log::Info("mat4 += mat4             %7.3f\n", result[3]);
115    Log::Info("mat4 = mat4.invert()     %7.3f\n", result[4]);
116}
117
118static void bench_half(int mode)
119{
120    float result[10] = { 0.0f };
121    Timer timer;
122
123    /* Set up tables */
124    float *pf = new float[HALF_TABLE_SIZE + 1];
125    half *ph = new half[HALF_TABLE_SIZE + 1];
126
127    for (size_t run = 0; run < HALF_RUNS; run++)
128    {
129        switch (mode)
130        {
131        case 1:
132            for (size_t i = 0; i < HALF_TABLE_SIZE + 1; i++)
133                ph[i] = half::makebits(rand());
134            break;
135        case 2:
136            for (size_t i = 0; i < HALF_TABLE_SIZE + 1; i++)
137                ph[i] = RandF(-2.0f, 2.0f);
138            break;
139        }
140
141        /* Copy float */
142        timer.GetMs();
143        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
144            pf[i] = pf[i + 1];
145        result[0] += timer.GetMs();
146
147        /* Convert half to float (array) */
148        timer.GetMs();
149        half::convert(pf, ph, HALF_TABLE_SIZE);
150        result[1] += timer.GetMs();
151
152        /* Convert half to float (fast) */
153        timer.GetMs();
154        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
155            pf[i] = (float)ph[i];
156        result[2] += timer.GetMs();
157
158        /* Add a half to every float */
159        timer.GetMs();
160        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
161            pf[i] += ph[i];
162        result[3] += timer.GetMs();
163
164        /* Copy half */
165        timer.GetMs();
166        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
167            ph[i] = ph[i + 1];
168        result[4] += timer.GetMs();
169
170        /* Change sign of every half */
171        timer.GetMs();
172        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
173            ph[i] = -ph[i];
174        result[5] += timer.GetMs();
175
176        /* Convert float to half (array) */
177        timer.GetMs();
178        half::convert(ph, pf, HALF_TABLE_SIZE);
179        result[6] += timer.GetMs();
180
181        /* Convert float to half (fast) */
182        timer.GetMs();
183        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
184            ph[i] = (half)pf[i];
185        result[7] += timer.GetMs();
186
187        /* Convert float to half (accurate) */
188        timer.GetMs();
189        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
190            ph[i] = half::makeaccurate(pf[i]);
191        result[8] += timer.GetMs();
192
193        /* Add a float to every half */
194        timer.GetMs();
195        for (size_t i = 0; i < HALF_TABLE_SIZE; i++)
196            ph[i] += pf[i];
197        result[9] += timer.GetMs();
198    }
199
200    delete[] pf;
201    delete[] ph;
202
203    for (size_t i = 0; i < sizeof(result) / sizeof(*result); i++)
204        result[i] *= 1000000.0f / (HALF_TABLE_SIZE * HALF_RUNS);
205
206    Log::Info("                          ns/elem\n");
207    Log::Info("float = float            %7.3f\n", result[0]);
208    Log::Info("float = half (array)     %7.3f\n", result[1]);
209    Log::Info("float = half (fast)      %7.3f\n", result[2]);
210    Log::Info("float += half            %7.3f\n", result[3]);
211    Log::Info("half = half              %7.3f\n", result[4]);
212    Log::Info("half = -half             %7.3f\n", result[5]);
213    Log::Info("half = float (array)     %7.3f\n", result[6]);
214    Log::Info("half = float (fast)      %7.3f\n", result[7]);
215    Log::Info("half = float (accurate)  %7.3f\n", result[8]);
216    Log::Info("half += float            %7.3f\n", result[9]);
217}
218
Note: See TracBrowser for help on using the repository browser.