Path: blob/main/test/benchmark/test_box2d_benchmark.cpp
4130 views
// Copyright 2013 The Emscripten Authors. All rights reserved.1// Emscripten is available under two separate licenses, the MIT license and the2// University of Illinois/NCSA Open Source License. Both these licenses can be3// found in the LICENSE file.456//7// Based on joelgwebber's Box2D benchmarks,8// https://github.com/joelgwebber/bench2d/blob/master/c/Bench2d.cpp9//101112// Settings =====================13// Turn this on to include the y-position of the top box in the output.14#define DEBUG 01516int WARMUP;17int FRAMES;1819typedef struct {20float mean;21float stddev;22} result_t;23// ==============================2425#include <cstdio>26#include <time.h>27#include <math.h>2829#ifdef __EMSCRIPTEN__30#include <emscripten.h>31#endif3233#if NO_PRINTING34#define printf(fmt, ...) (0)35#endif3637#include "Box2D/Box2D.h"3839using namespace std;4041const int e_count = 40;4243result_t measure(clock_t *times) {44float values[FRAMES];45result_t r;4647float total = 0;48for (int i = 0; i < FRAMES; ++i) {49values[i] = (float)times[i] / CLOCKS_PER_SEC * 1000;50total += values[i];51}52r.mean = total / FRAMES;5354float variance = 0;55for (int i = 0; i < FRAMES; ++i) {56float diff = values[i] - r.mean;57variance += diff * diff;58}59r.stddev = sqrt(variance / FRAMES);6061return r;62}6364b2World *world;65clock_t *times, minn = CLOCKS_PER_SEC * 1000 * 100, maxx = -1;66b2Body* topBody;67int32 frameCounter = 0;6869void iter();7071int main(int argc, char **argv) {72int arg = argc > 1 ? argv[1][0] - '0' : 3;73switch(arg) {74case 0: return 0; break;75case 1: WARMUP = 5; FRAMES = 35; break;76case 2: WARMUP = 32; FRAMES = 161; break;77case 3: WARMUP = 64; FRAMES = 333; break;78case 4: WARMUP = 5*64; FRAMES = 7*333; break;79case 5: WARMUP = 10*64; FRAMES = 17*333; break;80default: printf("error: %d\\n", arg); return -1;81}8283// do not split out warmup, do not ignore initial stalls84FRAMES += WARMUP;85WARMUP = 0;8687times = new clock_t[FRAMES];8889// Define the gravity vector.90b2Vec2 gravity(0.0f, -10.0f);9192// Construct a world object, which will hold and simulate the rigid bodies.93world = new b2World(gravity);94world->SetAllowSleeping(false);9596{97b2BodyDef bd;98b2Body* ground = world->CreateBody(&bd);99100b2EdgeShape shape;101shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));102ground->CreateFixture(&shape, 0.0f);103}104105{106float32 a = 0.5f;107b2PolygonShape shape;108shape.SetAsBox(a, a);109110b2Vec2 x(-7.0f, 0.75f);111b2Vec2 y;112b2Vec2 deltaX(0.5625f, 1);113b2Vec2 deltaY(1.125f, 0.0f);114115for (int32 i = 0; i < e_count; ++i) {116y = x;117118for (int32 j = i; j < e_count; ++j) {119b2BodyDef bd;120bd.type = b2_dynamicBody;121bd.position = y;122b2Body* body = world->CreateBody(&bd);123body->CreateFixture(&shape, 5.0f);124125topBody = body;126127y += deltaY;128}129130x += deltaX;131}132}133134for (int32 i = 0; i < WARMUP; ++i) {135world->Step(1.0f/60.0f, 3, 3);136}137138do {139iter();140} while (frameCounter <= FRAMES);141142return 0;143}144145void iter() {146if (frameCounter < FRAMES) {147clock_t start = clock();148world->Step(1.0f/60.0f, 3, 3);149clock_t end = clock();150clock_t curr = end - start;151times[frameCounter] = curr;152if (curr < minn) minn = curr;153if (curr > maxx) maxx = curr;154#if DEBUG155printf("%f :: ", topBody->GetPosition().y);156printf("%f\n", (float32)(end - start) / CLOCKS_PER_SEC * 1000);157#endif158frameCounter++;159return;160}161162// that's it!163164frameCounter++;165166result_t result = measure(times);167168printf("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);169}170171172173