HNHacker News
TopNewBestAskShowJobs

jblandy

55 karma · joined September 9, 2015

submissionscomments
jblandy··on What's Next for WebGPU
A better way to think about the problem is to recognize that the APIs and drivers are providing various services that pretty much every user is going to need, and which you will now need to reimplement yourself.

Nobody needs all of Vulkan, but everyone needs quite a bit of it. Buffer allocation? Command encoding? Scheduling? Synchronization? Abstracting GPU architecture differences (and GPUs vary a lot)? Render pipeline fixed-function stages like primitive assembly, tiling, and blending? You're signing up to implement all of that - good luck!

In this view, your idea is the assertion, "I could do a better job at all that stuff than the driver developers." Maybe so! They're only human. Drivers do have bugs. But you're only human too.

jblandy··on What's Next for WebGPU
Yes, this.
jblandy··on What's Next for WebGPU
The nice thing about WebGPU's "compat mode" is that it's designed so browsers don't have to implement it if they don't want to. Chrome is really excited about it; Safari has no plans to implement it, ever.

I agree that compat mode takes up more of the WebGPU standard committee's time than bindless. I'm not sure that's how I would prioritize things. (As a Mozilla engineer, we have more than enough implementation work to do already, so what the committee discusses is sort of beside the point for us...)

What would be really helpful is if, once the bindless proposal <https://hackmd.io/PCwnjLyVSqmLfTRSqH0viA?view> gets merged into the spec repo <https://github.com/gpuweb/gpuweb/tree/main/proposals>, a contributor could start adapting what WGPU has now to match the proposal. Implementation experience would be incredibly valuable feedback for the committee.

jblandy··on What's Next for WebGPU
There have been a bunch of significant improvements to WGPU's performance over the last few years.

* Before the major rework called "arcanization", `wgpu_core` used a locking design that caused huge amounts of contention in any multi-threaded program. It took write locks so often I doubt you could get much parallelism at all out of it. That's all been ripped out, and we've been evolving steadily towards a more limited and reasonable locking discipline.

* `wgpu_core` used to have a complex system of "suspected resources" and deferred cleanup, apparently to try to reduce the amount of work that needed to be done when a command buffer finished executing on the GPU. This turned out not to actually save any work at all: it did exactly the same amount of bookkeeping, just at a different time. We ripped out this complexity and got big speedups on some test cases.

* `wgpu_core` used to use Rust generics to generate, essentially, a separate copy of its entire code for each backend (Vulkan, Metal, D3D12) that it used. The idea was that the code generator would be able to see exactly what backend types and functions `wgpu_core` was using, inline stuff, optimize, etc. It also put our build times through the roof. So, to see if we could do something about the build times, Wumpf experimented with making the `wgpu_hal` API use dynamic dispatch instead. For reasons that are not clear to me, switching from generics to dynamic dispatch made WGPU faster --- substantially so on some benchmarks.

Animats posts frequently about performance problems they're running into, but when they do it's always this huge pile of unanalyzed data. It's almost as if, they run into a performance problem with their code, and then rather than figuring out what's going on themselves, they throw their whole app over the wall and ask WGPU to debug the problem. That is just not a service we offer.

jblandy··on What's Next for WebGPU
WGPU dev here. I agree with everything JMS55 says here, but I want to avoid a potential misunderstanding. Performance is definitely a priority for WGPU, the open source project. Much of WGPU's audience is very concerned with performance.

My team at Mozilla are active contributors to WGPU. For the moment, when we Mozilla engineers are prioritizing our own work, we are focused on compatibility and safety, because that's what we need most urgently for our use case. Once we have shipped WebGPU in Firefox, we will start putting our efforts into other things like performance, developer experience, and so on.

But WGPU has other contributors with other priorities. For example, WGPU just merged some additions to its nascent ray tracing support. That's not a Mozilla priority, but WGPU took the PR. Similarly for some recent extensions to 64-bit atomics (which I think is used by Bevy for Nanite-like techniques?), and other areas.

WGPU is an open source project. We at Mozilla contribute to the features we need; other people contribute to what they care about; and the overall direction of the project is determined by what capable contributors put in the time to make happen.

jblandy··on Learning systems programming with Rust
In the more theory-oriented departments this is possible.

It's easy to assume that the parts of CS you understand well are the important parts. It's the converse of the Blub Paradox. Might there be things that other people consider fundamental that you're only passingly familiar with?

At the meta-level: contempt (like that you're expressing) is a bit risky: it can be hard to tell whether it's motivated by a desire to uphold high standards, or the need for a quick bump to the self-esteem from putting someone else down. If it comes too easily or too often, I'd worry it might be the latter.

I was present at the keynote. I've worked on debuggers of one sort or another (GDB, and the JavaScript-level debugging API for Mozilla's SpiderMonkey engine) for two decades now, and I thought the keynote was an awesome hack.

Finally: https://xkcd.com/1053/

jblandy··on Why Rust? [pdf]
Yeah, that's a nice trick. I wonder how general it is, though.
jblandy··on Why Rust? [pdf]
It may be worth pointing out that the `Option<T>` type in Rust doesn't inherently involve any pointers at all, assuming `T` is not a pointer type itself.

For example, `Option<i32>` is probably (the compiler gets to choose) going to be represented as two four-byte values: the discriminant, which distinguishes the `Some` and `None` cases, and then a space for the value `v`, for when the discriminant says we have `Some(v)`. Since zero is a perfectly fine value for an `i32`, we have to store the discriminant separately.

But note that this is just a flat eight-byte value. There's no heap allocation involved. It's just as if you'd written in C:

    struct O { enum { Some, None } discriminant; int32_t value };
I compiled a program that uses `Option<Option<i32>>`, and looked at the DWARF debugging info to see what the compiler did with it. It seems to represent this as a twelve-byte value: four bytes for the discriminant for the outer `Option`, followed an eight-byte `Option<i32>` value laid out as before. Since you can get the address of a value held by an enum, I guess this makes sense; the compiler can't combine the discriminants or do anything clever like that.
jblandy··on Why Rust? [pdf]
And indeed, it's the representation Rust uses. When you have the type Option<T>, if Rust knows that a value of type T can never be zero (as is the case with pointer types), then the compiler uses zero as the machine-level representation for None, which indicates the absence of a value. I get into that a few paragraphs later.

What's important is that you can't use a value of type Option<T> as if it were T; you have to check it first. This is helpful for non-pointer types as well; I include an example of that.