Skip to content

perf(metal): Use Arcs rather than copying VertexBufferMappings - #10630

Merged
mergify[bot] merged 2 commits into
gfx-rs:trunkfrom
samoylenkodmitry:metal-vertex-buffer-ids
Oct 27, 2026
Merged

mergify[bot] merged 2 commits into
gfx-rs:trunkfrom
samoylenkodmitry:metal-vertex-buffer-ids

Conversation

@samoylenkodmitry

@samoylenkodmitry samoylenkodmitry commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Connections

None.

Description

Every pipeline switch (assign_from in mod.rs, called by set_render_pipeline) copies the bound pipeline's stage info into the pass state.

  • Before: extend_from_slice cloned each VertexBufferMapping. Each mapping owns an attributes: Vec<AttributeMapping>, so each clone allocated a new Vec. That was one allocation per vertex buffer, on every switch.
  • Now: Arc is used to share a reference to VertexBufferMapping between the pipeline and CommandState, rather than copying.

The change moves the cost from every pipeline switch to pipeline creation. A frame can switch pipelines thousands of times, while each pipeline is created once.

Allocations in one frame on Metal (Apple M5), counted with a counting global allocator. The frame alternates two pipelines with 2 vertex buffers each (this data is from an earlier version of the change that copied VBM IDs, but the effect on allocations should be similar):

switches per frame trunk allocations branch allocations
0 31 31
1,000 2,032 32
4,000 8,032 32

Testing

cargo xtask test --test wgpu-gpu on macOS 26, Apple M5 (Metal): 1128 of 1134 pass. The other 6 (naga snapshots, subgroup operations, passthrough shaders, a timestamp query) fail the same way on trunk on this machine.

Squash or Rebase?

One commit.

LLM Use?

Claude wrote the change and this description. I reviewed both.

Checklist

  • I self-reviewed and fully understand this PR.
  • CHANGELOG.md entries for the user-facing effects of this change are present.
  • The PR is minimal, and doesn't make sense to land as multiple PRs.
  • Commits are logically scoped and individually reviewable.
  • The PR description has enough context to understand the motivation and solution implemented.
  • This PR was automatically created by an Agent.
  • The description was automatically written by an Agent.

@andyleiserson

Copy link
Copy Markdown
Contributor

The absolute count of memory allocations is not a very meaningful performance metric. Do you have measurements that provide a bit more context? e.g. measure the time for a pipeline switch (either directly, or indirectly by measuring the frame time) before and after the change? How many pipeline switches do you actually have? Can you reduce the number by making the pipelines more generic?

This does look like a reasonable performance optimization, at least in the sense that the code is doing something inefficient, the proposed change looks functionally correct, and reduces the inefficiency. But I'm hesitant to make performance optimizations with an unclear or modest benefit based on the needs of one application. I also wonder whether we should eliminate this copying of stage info entirely and just store an Arc<metal::RenderPipeline> (there is one field that is modified in the command encoder state, so something would need to change about that, but I don't see any modification of most of the fields, including the vertex buffer mappings). Or Arc<[VertexBufferMapping]>. Or use SmallVec for the vertex attributes, but "unclear or modest benefit" also tends to apply to SmallVec changes (e.g. #10591).

@andyleiserson andyleiserson added the area: performance How fast things go label Oct 21, 2026
@samoylenkodmitry

Copy link
Copy Markdown
Contributor Author

agree about the smallness of the gains. Fixed to arc as was suggested in case it would be merged.

@andyleiserson andyleiserson changed the title perf(metal): Copy only vertex buffer ids on pipeline switch perf(metal): Use Arcs rather than copying VertexBufferMappings Oct 26, 2026

@andyleiserson andyleiserson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix.

@andyleiserson

Copy link
Copy Markdown
Contributor

@Mergifyio queue

@mergify mergify Bot added the queue: queued Set by Mergify while the PR is in the merge queue label Oct 26, 2026
@mergify mergify Bot added queue: dequeued Set by Mergify when the PR left the merge queue without merging and removed queue: queued Set by Mergify while the PR is in the merge queue labels Oct 26, 2026
@mergify

mergify Bot commented Oct 26, 2026

Copy link
Copy Markdown

@samoylenkodmitry Mergify removed this PR from the merge queue. Reason: CHECKS_INTERRUPTED. See the Mergify check for details.

@andyleiserson

Copy link
Copy Markdown
Contributor

@Mergifyio queue

@mergify mergify Bot added queue: queued Set by Mergify while the PR is in the merge queue and removed queue: dequeued Set by Mergify when the PR left the merge queue without merging labels Oct 26, 2026
@mergify mergify Bot added queue: dequeued Set by Mergify when the PR left the merge queue without merging and removed queue: queued Set by Mergify while the PR is in the merge queue labels Oct 26, 2026
@mergify

mergify Bot commented Oct 26, 2026

Copy link
Copy Markdown

@samoylenkodmitry Mergify removed this PR from the merge queue. Reason: CHECKS_FAILED. See the Mergify check for details.

@andyleiserson

Copy link
Copy Markdown
Contributor

@Mergifyio queue

@mergify mergify Bot added the queue: queued Set by Mergify while the PR is in the merge queue label Oct 27, 2026
@mergify mergify Bot removed the queue: dequeued Set by Mergify when the PR left the merge queue without merging label Oct 27, 2026
@mergify
mergify Bot merged commit 466dc0b into gfx-rs:trunk Oct 27, 2026
76 checks passed
@github-project-automation github-project-automation Bot moved this from Small to Done in Triage Oct 27, 2026
@mergify mergify Bot removed the queue: queued Set by Mergify while the PR is in the merge queue label Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: performance How fast things go

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants