983
983

Reputation: 54

Downloading WebGPU buffer with await mapAsync is 5000 times slower in Firefox Nightly

I want to download a WebGPU buffer to host memory in order to do some computation on the CPU. Unfortunately, I have measured that WebGPU is 5000 slower than expected in Firefox Nightly (128.0a1) on Ubuntu 22.04. It takes approximately 100 milliseconds to download a buffer, while the equivalent CuPy code takes only 0.02 milliseconds.

CuPy code for reference:

import cupy as cp
import time

buf = cp.array([1, 2, 3])

for _ in range(10):
    # Synchronize to make sure we are really measuring the correct time (not strictly necessary since .get() synchronizes implicitly)
    cp.cuda.Stream.null.synchronize()
    start_time = time.perf_counter()

    values = buf.get()

    cp.cuda.Stream.null.synchronize()
    elapsed_time = time.perf_counter() - start_time

    print(f"values: {values}, {elapsed_time * 1000:.6f} milliseconds")

The following JavaScript code

  1. Creates a WebGPU buffer from values [1, 2, 3]
  2. Copies the WebGPU buffer to an intermediate read-back buffer
  3. Reads the values from the read-back buffer into the values array while measuring the time it takes to do so.
async function main(){
    if (!navigator.gpu) alert("WebGPU not supported");
    const adapter = await navigator.gpu.requestAdapter();
    if (!adapter) alert("WebGPU not supported");
    const device = await adapter.requestDevice();
    if (!device) alert("WebGPU not supported");
    const values = new Float32Array([1, 2, 3]);

    // Create GPU buffer for values
    const buffer = device.createBuffer({
        size: values.byteLength,
        usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
        mappedAtCreation: true,
    });

    // Copy values to GPU buffer
    new values.constructor(buffer.getMappedRange()).set(values);
    buffer.unmap();

    // Create readback buffer
    const readBuffer = device.createBuffer({
        size: values.byteLength,
        usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
    });

    // Measure 10 times to make sure it was not a fluke
    for (var iteration = 0; iteration < 10; iteration++){
        let startTime = window.performance.now();

        // Copy buffer to readback buffer
        const commandEncoder = device.createCommandEncoder();
        commandEncoder.copyBufferToBuffer(buffer, 0, readBuffer, 0, values.byteLength);
        device.queue.submit([commandEncoder.finish()]);

        // Wait for the GPU to finish
        await readBuffer.mapAsync(GPUMapMode.READ);

        // Clear values to make sure we are really reading from the buffer
        values.fill(0);

        // Copy values from readback buffer
        values.set(new values.constructor(readBuffer.getMappedRange()));

        // Unmap the readback buffer so we can use it again next iteration
        readBuffer.unmap();

        // Measure elapsed time
        let elapsedTime = window.performance.now() - startTime;

        console.log("values", values, "time", elapsedTime, "milliseconds");
    }
}

main();

In Chrome Unstable, the same code takes about 2 milliseconds per iteration, which makes me suspect this is a bug in Firefox Nightly, but I wanted to ask here anyway in case I missed something.

Upvotes: -1

Views: 180

Answers (1)

passThru
passThru

Reputation: 11

According to Mozilla...

“Nightly is an unstable testing and development platform.”

In other words, it is a BETA software release of a future version... so you’re wasting everyone’s time here!

If you’re a beta-tester then you should know exactly where/how to report bugs to Mozilla, but you shouldn’t present issues here as though they are legit technical problems of a stable release!

Upvotes: 1

Related Questions