Code Monkey home page Code Monkey logo

slow-wasm-vec-dtor's Introduction

Slow std::vector WASM Demonstration

Overview

Benchmark that compares two methods of creating an image buffer in terms of performance. The most interesting results come when you run it via the WebAssembly target (build instructions below)

Results

Below are the results I saw on my machine. Notice the absurd destruction times on WASM in both Chrome and Firefox when using std::vector, and how not-absurd they are when running natively or when using raw new/delete calls against a uint8_t*.

NATIVE (x86 Release, MSVC):

---------- std::vector image benchmarks ----------
 size|         bytes|      alloc ms|       fill ms|       dtor ms
  256|         65536|             0|             0|             0
  512|        262144|             0|             1|             0
 1024|       1048576|             0|             5|             0
 2048|       4194304|             0|            23|             0
 4096|      16777216|             2|           168|             1


---------- std::string image benchmarks ----------
 size|         bytes|      alloc ms|       fill ms|       dtor ms
  256|         65536|             0|             0|             0
  512|        262144|             0|             1|             0
 1024|       1048576|             0|             5|             0
 2048|       4194304|             0|            23|             0
 4096|      16777216|             2|           167|             1


---------- raw image benchmarks ----------
 size|         bytes|      alloc ms|       fill ms|       dtor ms
  256|         65536|             0|             0|             0
  512|        262144|             0|             1|             0
 1024|       1048576|             0|             6|             0
 2048|       4194304|             0|            32|             0
 4096|      16777216|             0|           171|             1

WASM (Firefox 82, Windows)

---------- std::vector image benchmarks ----------
 size|         bytes|      alloc ms|       fill ms|       dtor ms
  256|         65536|             2|             1|             3
  512|        262144|             6|             8|             3
 1024|       1048576|            13|             8|            11
 2048|       4194304|            50|            33|            44
 4096|      16777216|           197|           180|           173


---------- std::string image benchmarks ----------
 size|         bytes|      alloc ms|       fill ms|       dtor ms
  256|         65536|             0|             0|             0
  512|        262144|             0|             2|             0
 1024|       1048576|             0|             8|             0
 2048|       4194304|             0|            32|             0
 4096|      16777216|             1|           167|             0


---------- raw image benchmarks ----------
 size|         bytes|      alloc ms|       fill ms|       dtor ms
  256|         65536|             0|             0|             0
  512|        262144|             0|             1|             0
 1024|       1048576|             0|             8|             0
 2048|       4194304|             0|            33|             0
 4096|      16777216|             0|           171|             0

WASM (Chrome 86, Windows)

---------- std::vector image benchmarks ----------
 size|         bytes|      alloc ms|       fill ms|       dtor ms
  256|         65536|             0|             0|             0
  512|        262144|             3|             2|             3
 1024|       1048576|            15|            10|            13
 2048|       4194304|            59|            41|            55
 4096|      16777216|           241|           184|           219


---------- std::string image benchmarks ----------
 size|         bytes|      alloc ms|       fill ms|       dtor ms
  256|         65536|             0|             0|             0
  512|        262144|             0|             2|             0
 1024|       1048576|             0|             9|             0
 2048|       4194304|             0|            41|             0
 4096|      16777216|             1|           181|             0


---------- raw image benchmarks ----------
 size|         bytes|      alloc ms|       fill ms|       dtor ms
  256|         65536|             0|             0|             0
  512|        262144|             0|             2|             0
 1024|       1048576|             0|            10|             0
 2048|       4194304|             0|            39|             0
 4096|      16777216|             0|           186|             0

Building / Running

Native

Ninja:

mkdir out
cd out
cmake ..
ninja vec_benchmark
vec_benchmark

Visual Studio

mkdir out
cd out
cmake ..

Open the Visual Studio solution file created in out and run the program

WebAssembly

Download and install Emscripten

Then, build the program:

mkdir ems_out
cd ems_out
emcmake cmake ..
emmake ninja vec_benchmark

(I use ninja - you might use make or something else, in which case you'll use emmake make vec_benchmark etc)

Then, start up a web server:

# If you have Python installed
python -m SimpleHTTPServer
# Or, if you have http-server NPM package:
http-server

And navigate to http://localhost:8000/vec_benchmark.html in your favorite browser.

Le Backstory

I've been playing with the idea of developing a C++ game that has a native build target as well as a Web target (via WebAssembly compiled with Emscripten). I'm having remarkable luck with it, but there are a few tricky things that pop up here and there.

One particularly alarming case was when I was working on initialization code - i.e., the stuff that happens during the loading screen. I noticed that there were a few huge CPU stutters, even when I was using worker threads (via WebWorkers) to do heavy CPU work off the UI thread.

After a lot of hair pulling, I found that the delay was happening specifically during the "Update" cycle when a high resolution image was loaded - specifically, a 2048x2048 image containing the roughness map for a PBR material.

Tons and tons of benchmarking later, I found out that the problem was happening through a long line of destructors that was triggered when a std::function was going out of scope that contained a std::shared_ptr in its closure which... several layers deeper, contained the large std::vector<uint8_t> which holds the raw pixel data for that roughness map texture.

I replaced the std::vector<uint8_t> with a naked uint8_t* pointer type to determine if the offender was the WASM implementation of malloc/free that was problematic, only to discover that... it wasn't. For some reason, most of the time spent in my loading screens were being spent in the std::vector<uint8_t> destructor of all places.

slow-wasm-vec-dtor's People

Contributors

sessamekesh avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.