Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Difference between Float32Array::new().subarray and Float32Array::view() #1615

Closed
dakom opened this issue Jun 23, 2019 · 5 comments
Closed
Labels

Comments

@dakom
Copy link
Contributor

dakom commented Jun 23, 2019

Summary

The docs show Float32Array::view() as unsafe while the webgl example does not use this function - rather it uses a combo of Float32Array::new() and Float32Array::subarray

Is there a performance tradeoff happening with this approach, that would be gained by switching to view() ?

Additional Details

If we are always able to get a view into Float32Array, without really allocating, I wonder if we actually gain from bufferSubData() ? (e.g. https://docs.rs/web-sys/0.3.7/web_sys/struct.WebGl2RenderingContext.html#method.buffer_sub_data_with_i32_and_array_buffer)

@dakom dakom added the question label Jun 23, 2019
alexcrichton added a commit to alexcrichton/wasm-bindgen that referenced this issue Jun 23, 2019
@alexcrichton
Copy link
Contributor

Is there a performance tradeoff happening with this approach, that would be gained by switching to view() ?

Ah that was just an old example which predated the existence of view, I've sent a PR to update it since using view is more idiomatic!

If we are always able to get a view into Float32Array, without really allocating, I wonder if we actually gain from bufferSubData() ? (

I think so! I believe that's a method on WebGl2RenderingContext though while the example is currently using WebGlRenderingContext (lack of 2)

@dakom

This comment was marked as abuse.

@alexcrichton
Copy link
Contributor

Oh no you're right about the perf optimization, I think it's just that webgl doesn't have support for that but webgl2 does.

@alexcrichton
Copy link
Contributor

Closing with the example update in #1618

@Pauan
Copy link
Contributor

Pauan commented Aug 14, 2019

@dakom (Little late, but...)

The reason for bufferSubData in WebGL2 isn't to avoid copying.

When you call view in Rust, it doesn't need to copy the memory, but it still has to allocate a new JS Float32Array object, and then use that object, and then garbage collect it.

When the bufferSubData method is called a lot, this extra allocation and garbage collection can have a significant cost.

So the point of bufferSubData is that it doesn't need to create a new Float32Array object.

In other words, with WebGL1 the Rust code looks like this (including the code for view):

unsafe fn view(slice: &[f32]) -> Float32Array {
    let buf = wasm_bindgen::memory();
    let mem = buf.unchecked_ref::<WebAssembly::Memory>();

    // Allocates a new Float32Array object in JS
    Float32Array::new_with_byte_offset_and_length(
        &mem.buffer(),
        slice.as_ptr() as u32,
        slice.len() as u32,
    )
}

gl.buffer_sub_data_with_i32_and_array_buffer_view(
    target,
    offset,
    &unsafe { view(&slice) },
);

But with WebGL2 it would look like this:

let buf = wasm_bindgen::memory();
let mem = buf.unchecked_ref::<WebAssembly::Memory>();

gl.buffer_sub_data_with_i32_and_array_buffer_view(
    target,
    offset,
    &mem.buffer(),
    slice.as_ptr() as u32,
    slice.len() as u32,
);

Note the lack of needing to create a new Float32Array object, it can just index into the wasm memory directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants