-
Notifications
You must be signed in to change notification settings - Fork 928
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using global constant arrays produces slow Metal code #4367
Comments
Here's what Google's Tint does with the example above:
The semantics expressed are certainly run-time initialization, like Naga. But of course, since the issue here is inconsistent optimization (in some cases, Naga's output was fine), I don't think we can really say whether this is better or worse. It seems safe to assume, though, that if we generate a global constant initialized at compile time, it's unlikely that any code generator along the path to the GPU would introduce run-time copies. |
Thank you for writing this down!
I'm not actually sure if that's a problem. I thought the problem was with code we inject to copy an array element-by-element, but this here is a bulk copy. Obviously can be improved, but I'd like us to not lose sight of what the actual issue is. A test case, maybe within https://github.com/kvark/wgpu-bench, would help. |
Yes, a test case would be good. I was trying to capture what was described as the problem in matrix chat. |
On a shader I'm using, this issue causes a 3x slowdown (from ~700us to 2ms). |
Are you on the latest version (0.13)? We got rid of the loop initialization in the latest release (in gfx-rs/naga#2331) which was thought to be the cause of the slowdown. |
Yes. The relevant generated code is:
If instead the array is defined as:
And is accessed directly by |
Would defining the array as a global A |
It would, if I wouldn't need to access it with a dynamic index. |
Ah, forgot we don't support that yet. See #4337. |
We generate Metal Shading Language code that runs slowly on some Apple devices, for shaders that index a large global constant array. The generated code copies a global constant into a function-local array every time the function is called; if the constant is large, this is expensive.
For the following input:
We generate the following MSL:
This declares a global constant
const_type1_
, whichaccess_array
copies into the local variableconstant_array
each time it's called. For this example it's probably not a big deal, but people use big data tables, so the copy can be expensive.Naga introduces this copy because MSL doesn't support mutable global arrays. Metal Shading Language Specification 2.4 §4, "Address Spaces", says, "The address space for a variable at program scope must be constant." Further, §4.2 says, "Variables in program scope must be declared in the
constant
address space and initialized during the declaration statement."WGSL suggests that people use
let
for global constants, but the author can't uselet
here, since WGSL can't index arrays unless they're in memory.What Naga should do when generating Metal (and what other toolchains seem to do now) is recognize that
constant_array
is not actually ever assigned to, generate a global variable in the Metalconstant
address space, and refer to that directly from function bodies.The text was updated successfully, but these errors were encountered: