Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/test/benchmark/test_box2d_benchmark.cpp
4130 views
1
// Copyright 2013 The Emscripten Authors. All rights reserved.
2
// Emscripten is available under two separate licenses, the MIT license and the
3
// University of Illinois/NCSA Open Source License. Both these licenses can be
4
// found in the LICENSE file.
5
6
7
//
8
// Based on joelgwebber's Box2D benchmarks,
9
// https://github.com/joelgwebber/bench2d/blob/master/c/Bench2d.cpp
10
//
11
12
13
// Settings =====================
14
// Turn this on to include the y-position of the top box in the output.
15
#define DEBUG 0
16
17
int WARMUP;
18
int FRAMES;
19
20
typedef struct {
21
float mean;
22
float stddev;
23
} result_t;
24
// ==============================
25
26
#include <cstdio>
27
#include <time.h>
28
#include <math.h>
29
30
#ifdef __EMSCRIPTEN__
31
#include <emscripten.h>
32
#endif
33
34
#if NO_PRINTING
35
#define printf(fmt, ...) (0)
36
#endif
37
38
#include "Box2D/Box2D.h"
39
40
using namespace std;
41
42
const int e_count = 40;
43
44
result_t measure(clock_t *times) {
45
float values[FRAMES];
46
result_t r;
47
48
float total = 0;
49
for (int i = 0; i < FRAMES; ++i) {
50
values[i] = (float)times[i] / CLOCKS_PER_SEC * 1000;
51
total += values[i];
52
}
53
r.mean = total / FRAMES;
54
55
float variance = 0;
56
for (int i = 0; i < FRAMES; ++i) {
57
float diff = values[i] - r.mean;
58
variance += diff * diff;
59
}
60
r.stddev = sqrt(variance / FRAMES);
61
62
return r;
63
}
64
65
b2World *world;
66
clock_t *times, minn = CLOCKS_PER_SEC * 1000 * 100, maxx = -1;
67
b2Body* topBody;
68
int32 frameCounter = 0;
69
70
void iter();
71
72
int main(int argc, char **argv) {
73
int arg = argc > 1 ? argv[1][0] - '0' : 3;
74
switch(arg) {
75
case 0: return 0; break;
76
case 1: WARMUP = 5; FRAMES = 35; break;
77
case 2: WARMUP = 32; FRAMES = 161; break;
78
case 3: WARMUP = 64; FRAMES = 333; break;
79
case 4: WARMUP = 5*64; FRAMES = 7*333; break;
80
case 5: WARMUP = 10*64; FRAMES = 17*333; break;
81
default: printf("error: %d\\n", arg); return -1;
82
}
83
84
// do not split out warmup, do not ignore initial stalls
85
FRAMES += WARMUP;
86
WARMUP = 0;
87
88
times = new clock_t[FRAMES];
89
90
// Define the gravity vector.
91
b2Vec2 gravity(0.0f, -10.0f);
92
93
// Construct a world object, which will hold and simulate the rigid bodies.
94
world = new b2World(gravity);
95
world->SetAllowSleeping(false);
96
97
{
98
b2BodyDef bd;
99
b2Body* ground = world->CreateBody(&bd);
100
101
b2EdgeShape shape;
102
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
103
ground->CreateFixture(&shape, 0.0f);
104
}
105
106
{
107
float32 a = 0.5f;
108
b2PolygonShape shape;
109
shape.SetAsBox(a, a);
110
111
b2Vec2 x(-7.0f, 0.75f);
112
b2Vec2 y;
113
b2Vec2 deltaX(0.5625f, 1);
114
b2Vec2 deltaY(1.125f, 0.0f);
115
116
for (int32 i = 0; i < e_count; ++i) {
117
y = x;
118
119
for (int32 j = i; j < e_count; ++j) {
120
b2BodyDef bd;
121
bd.type = b2_dynamicBody;
122
bd.position = y;
123
b2Body* body = world->CreateBody(&bd);
124
body->CreateFixture(&shape, 5.0f);
125
126
topBody = body;
127
128
y += deltaY;
129
}
130
131
x += deltaX;
132
}
133
}
134
135
for (int32 i = 0; i < WARMUP; ++i) {
136
world->Step(1.0f/60.0f, 3, 3);
137
}
138
139
do {
140
iter();
141
} while (frameCounter <= FRAMES);
142
143
return 0;
144
}
145
146
void iter() {
147
if (frameCounter < FRAMES) {
148
clock_t start = clock();
149
world->Step(1.0f/60.0f, 3, 3);
150
clock_t end = clock();
151
clock_t curr = end - start;
152
times[frameCounter] = curr;
153
if (curr < minn) minn = curr;
154
if (curr > maxx) maxx = curr;
155
#if DEBUG
156
printf("%f :: ", topBody->GetPosition().y);
157
printf("%f\n", (float32)(end - start) / CLOCKS_PER_SEC * 1000);
158
#endif
159
frameCounter++;
160
return;
161
}
162
163
// that's it!
164
165
frameCounter++;
166
167
result_t result = measure(times);
168
169
printf("frame averages: %.3f +- %.3f, range: %.3f to %.3f \n", result.mean, result.stddev, float(minn)/CLOCKS_PER_SEC * 1000, float(maxx)/CLOCKS_PER_SEC * 1000);
170
}
171
172
173