GPUQueue.writeBuffer is slow
Categories
(Core :: Graphics: WebGPU, defect, P1)
Tracking
()
People
(Reporter: jimb, Unassigned)
References
(Blocks 2 open bugs)
Details
(Keywords: leave-open)
Attachments
(1 external file)
We believe that the performance of many of our WebGPU MVP apps is affected by GPUQueue.writeBuffer performance being very poor.
This profile of the Marching Cubes WebGPU sample shows that, of a 283ms requestAnimationFrame call, 41.7ms are spent in GPUQueue.writeBuffer calls. Obviously this profile has other problems as well, but we have observed that GPUQueue.writeBuffer shows up in many applications' profiles.
It seems like most of the time is in mozilla::ipc::shared_memory::Create, mozilla::ipc::shared_memory::Handle::Map, and mozilla::ipc::shared_memory::MappingBase::~MappingBase. Is it possible that we're creating a fresh shmem for every call?
Updated•1 year ago
|
Comment 1•1 year ago
•
|
||
Is it possible that we're creating a fresh shmem for every call?
Comment 2•1 year ago
|
||
2 unity demos and project prismatic stutter/have low FPS and looking at profiles it seems that GPUQueue.writeBuffer is the main bottleneck:
- https://skinning-demo.cds.unity3d.com in Bug 1963161, spends ~70% of time in
GPUQueue.writeBufferhttps://share.firefox.dev/3H45Y0X - https://boat-demo.cds.unity3d.com in Bug 1963161, spends ~71% of time in
GPUQueue.writeBufferhttps://share.firefox.dev/3Fr2DIP - https://www.crazygames.com/game/project-prismatic in Bug 1954080, spends ~58% of time in
GPUQueue.writeBufferhttps://share.firefox.dev/3Skwoy6
Comment 3•1 year ago
|
||
I added a profiler marker for GPUQueue.writeBuffer and here are the results (keep in mind these are per frame):
- Skinning Demo: 4466 calls, with a max size of 768b (most are 768b), https://share.firefox.dev/3Ffn8IB
- Boat Demo: 2112 calls, with a max size of 138816b (most are 768b), https://share.firefox.dev/4k9AnJS
- Project Prismatic: 1466 calls, with a max size of 44384 (most are 256-3kb), https://share.firefox.dev/4muKiLC
- Marching Cubes: 194 calls, with a max size of 176 (most are 4b), https://share.firefox.dev/4dvzjgQ
Looking at the parts that make up GPUQueue.writeBuffer:
| Name | mozilla::ipc::IProtocol::ChannelSend |
total shmem | create shmem | map shmem | unmap shmem |
|---|---|---|---|---|---|
| Skinning Demo | 58% | 28.1% | 12% | 6.1% | 10% |
| Boat Demo | 50% | 36.6% | 17% | 7.6% | 12% |
| Project Prismatic | 54% | 34.2% | 16% | 6.2% | 12% |
| Marching Cubes | 34% | 44.3% | 15.3% | 12% | 17% |
Talking with Nical and JimB in our matrix channel, we think we can speed up GPUQueue.writeBuffer in two ways:
- Reuse shmem by introducing a pool (full logic TBD)
- Reduce overhead of IPDL: Bug 1968122
| Reporter | ||
Comment 4•1 year ago
|
||
Removed 1937100 as a blocker, since this bug has nothing to do with GC.
Updated•1 year ago
|
Comment 5•1 year ago
|
||
Updated•1 year ago
|
Comment 6•1 year ago
|
||
D253549 slightly improves performance but the main overhead is IPDL calls (Bug 1968122).
I should be able to put up the patch stack for Bug 1968122 today, it improves performance even more (the content timeline is now nearly empty) but apps making heavy use of GPUQueue.writeBuffer are still stuttering since we create and destroy a staging buffer for each writeBuffer call in wgpu.
The obvious solution would be to reuse staging buffers and we might end up doing that but I wonder if those writeBuffer calls only write to a few destination buffers, if they do, we could coalesce the calls since we are already buffering them.
Comment 8•1 year ago
|
||
| bugherder | ||
| Reporter | ||
Updated•1 year ago
|
Comment 9•1 year ago
|
||
A possible optimization for CPU-backed buffers would be to map them and copy the data directly without an additional staging buffer.
Updated•1 year ago
|
Updated•1 year ago
|
Description
•