What is the new `mutability` property of MTLPipelineBufferDescriptor?

MTLComputePipelineDescriptor has a new property `buffers` in the iOS 11 Beta. It's possible to set a buffer as immutable via the `mutability` property.

The documentation says:


"The Metal driver may perform certain optimizations if you specify that neither the CPU nor the GPU will modify a buffer's contents between the time the buffer is set in a function's argument table and the time its associated command buffer completes execution." [emphasis mine]


I'm confused. Isn't immutability of a buffer specified via the `constant` memory-layout keyword in a kernel function?

What is the difference between:

  1. specifying a buffer to be in the `constant` address space in a kernel function
  2. specifying the buffer to be immutable via the pipeline descriptor, as mentioned above?


Is the second approach better than the first, or should I combine them? Which is faster (and what does it depend on)?

Accepted Reply

Using the constant address space just says you cannot change the contents of buffer by writting to it in the shader / kernel that specifies the constant address space. If your pipeline sets a buffer index to immutable, then you're telling Metal that you will not change the contents of the buffer at that index after it has been set in the encoder (i.e. you cannot change the a buffer set at an immutable index either by accessing the buffer's data with the CPU via the buffer's contents property nor by writing to the buffer using the GPU in a shader or kernel).


This was mainly added for Argument Buffers. There's some optimizations that a driver can apply if you're gaurantting that you will not change any arguments specified in an argument buffer after it's been set. For buffers that don't contain arguments, there is little difference whether the buffer index is marked as immutable or not. (This *could* potentially change with future hardware and releases, but it's unlikely).


Only devices that support the Tier 2 argument buffer feature set can set the index of a buffer containing arguments as mutable. Devices supporting the Tier 1 argument buffer feature set must set any buffer index containing argument to immutable. Note these restrictions only applies to buffers containing arguments and does not apply to standard buffer containing only data to be fetched by the kernels and shaders).

Replies

Mornin'


Few guesses:

1) (of this I am sure) Not modifying on CPU means that Metal doesn't have to copy your buffer content on setting, sparing one memcpy (and perhaps a memory allocation). But then I guess you should rather be careful with what you pass there, for example if your buffer is on stack, and function returns without waiting for execution to complete, then you'll get nasty unpredictable, bug. This is not what you get with 'constant' memory layout in kernel function, since it only describes where buffer data resides in on GPU side.

2) (now I am just guessing) AFAIR you can't always use constant address space, for example for reasons like buffer size (constant is pretty limited, if I remember well). So perhaps Metal can switch that on and off automatically, depending on the particular buffer size?

3) (even more guessing) Caching optimisations? Kinda like things you render too, where you can also specify what to do with contents before/after processing (Load/Store settings). Perhaps some device caches buffers somewhere, and it is a performance win if you can discard that cache, not having to store contents back in device memory?


Regards

Michal

Thank you Michal.


I find your guesses reasonable. The fact that Apple haven't highlighted the mutability property in any of the WWDC sessions and that the property isn't described in detail would suggest it's a minor feature.


However, it'd be great if someone from the Apple staff on this forum could write more about it or at least confirm/deny your guesses.

Using the constant address space just says you cannot change the contents of buffer by writting to it in the shader / kernel that specifies the constant address space. If your pipeline sets a buffer index to immutable, then you're telling Metal that you will not change the contents of the buffer at that index after it has been set in the encoder (i.e. you cannot change the a buffer set at an immutable index either by accessing the buffer's data with the CPU via the buffer's contents property nor by writing to the buffer using the GPU in a shader or kernel).


This was mainly added for Argument Buffers. There's some optimizations that a driver can apply if you're gaurantting that you will not change any arguments specified in an argument buffer after it's been set. For buffers that don't contain arguments, there is little difference whether the buffer index is marked as immutable or not. (This *could* potentially change with future hardware and releases, but it's unlikely).


Only devices that support the Tier 2 argument buffer feature set can set the index of a buffer containing arguments as mutable. Devices supporting the Tier 1 argument buffer feature set must set any buffer index containing argument to immutable. Note these restrictions only applies to buffers containing arguments and does not apply to standard buffer containing only data to be fetched by the kernels and shaders).