Skip to content

Performance Tips

Dzmitry Malyshau edited this page Jan 16, 2020 · 2 revisions

This page describes the best practices of working with gfx-rs for users that demand maximum performance.

General

Object creation

Creation of pipelines can be slow, allocation of memory can be slow. Creation and writing of descriptor sets can also be slow. Try to re-use existing objects.

Iterators

The API is based on iterators for the most part. Do use them if that helps avoiding to collect things. Note, however, that gfx-rs does not guarantee that the iteration will happen, so don't put any correctness mutable logic in there.

Metal

Pass switches

Metal natively separates all the work into compute/transfer/render passes. There is overhead, therefore, to switching your work between compute/transfer. Try to group them together, avoid the pattern like:

comb.copy_buffer(...); // transfer
comb.dispatch(...);  // compute
comb.copy_image_to_buffer(...); // transfer
comb.set_compute_pipeline(...); // compute

Memory aliasing

We don't use Metal memory aliasing, so be prepared to see your alias-optimized application to perform slower.

Render passes

Beginning a render pass is an exceptionally heavy operation in Metal. Additionally, the backend resets all the relevant state that exists in Vulkan but doesn't exist (outside of a render pass) in Metal. Therefore, try to set all the relevant state (viewports, scissors, pipelines, descriptor sets, etc) before starting a render pass.

D3D12

Image transfers

Do respect the Limit::optimal_buffer_copy_* values in order to hit the fast path on resource copies. Otherwise, the backend would have to split a larger copy into multiple smaller ones (e.g. one per row).