WICG / turtledove

TURTLEDOVE
https://wicg.github.io/turtledove/
Other
538 stars 237 forks source link

WASM Recommendations: Bidding Function + WASM Using Emscripten #1136

Open thegreatfatzby opened 7 months ago

thegreatfatzby commented 7 months ago

Hi fwends, standard sheepish preamble that I haven't used WASM before, and I'm sure getting deeper on it is revealing holes in my understanding of many things...that out of the way.

The tldr question is whether the approach below is directionally right for using WASM with your bidding function, or whether there's something easy I'm missing.

  1. Write amazing code in C/C++.
  2. Compile using Emscripten (ES), get both the WASM binary and the glue JS file it generates, preferably using the "MODULARIZE" compile flag so that you get the Module creation code as a function, rather than executed on load.
  3. Add your generateBid code at the end of the JS file with the glue, and in generateBid create WebAssembly.instance using the browserSignals.wasmHelper Module that the framework already created.
  4. Use ccall/cwrap from that point to invoke your functions.
  5. Profit.

edit: example here.

If there's some docs I've missed let me know, I dug around and found a test file in Chromium that I can't get to work IRL (it doesn't have the necessary imports ES generates for the glue JS) and various bits in different tickets. This seems to work and is fine to get going for now, but I am wondering if there's a more recommended approach.

Little More Detail

Is it right that the browserSignals.wasmHelper instance of WebAssembly.Module is only created once behind the scenes in Chromium space, and then that single instance is passed to generateBid? I guess the ^ approach means that the ES Module object is created once per call to generateBid, when it only "needs" to be created once?

I think this would be ES compiler specific, but if we could provide the glue code separately (i.e. IG.biddingWASMEmscriptenGlue or some such) then the framework could just pass that in and result in less Module creation? It would also allow for those things to be decoupled a bit more.

morlovich commented 7 months ago

So I am too unfamiliar with the usual tooling to answer your first part, but can answer the detail portion:

Each call of generateBid gets a fresh Module object (it basically has to in the default executionMode, otherwise it would mess with isolation), but they all share the underlying "compiled WASM" stuff, so it's a pretty cheap operation.

thegreatfatzby commented 7 months ago

@morlovich thanks for the quick reply...when you say Each call of generateBid gets a fresh Module object, do you mean the WebAssembly.Module that gets passed in via browserSignals.wasmHelper? I'm still learning this space but it seems like there's a WebAssembly.Module that is distinct from the Emscripten Module, which I take to only have meaning in the Emscripten space, and WASM doesn't know about it.

morlovich commented 7 months ago

Yeah, WebAssembly.Module. Sorry, don't know much about Emscripten.

dmdabbs commented 7 months ago

Each call of generateBid gets a fresh Module object (it basically has to in the default executionMode, otherwise it would mess with isolation), but they all share the underlying "compiled WASM" stuff, so it's a pretty cheap operation.

The spec says that each call to generateBid (for an IG with wasmHelperURL) must fetch WebAssembly. Is it correct then that if the response body binary is in the global HTTP cache then it is only a relatively inexpensive compile to create the fresh object?

MattMenke2 commented 7 months ago

The spec isn't accurate - we don't re-fetch the WebAssembly if two objects can share a live executor (See the implementation overview for what that means).

That aside, we do obey HTTP caching semantics for the WebAssembly fetch. We will eventually need to think about what network partition we use for that, since fetching that from any partition potentially leaks data - currently, we use the buyer's network partition (For more details on partitioning, see the fetch spec).

dmdabbs commented 7 months ago

The spec isn't accurate - we don't re-fetch the WebAssembly if two objects can share a live executor (See the implementation overview for what that means).

👍

myonlinematters commented 6 months ago

see my writup here "WASM and It's Use in the Sandbox " here - www.theprivacysandbox.com if that helps.

May be too basic for what you are asking - but it does cover emscripten - which is interesting but there are other tools to look at:

WASmFiddle https://anonyco.github.io/WasmFiddlePlusPlus/ WasmExplorer: https://mbebenita.github.io/WasmExplorer/ WebAssembly Tools: https://webassembly.org/getting-started/advanced-tools/ Text-entry language for Wasm https://www.assemblyscript.org/