-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
CA1857: hundred or thousands of build warnings from System.Runtime.Intrinsics.X86 on updating from .NET 7.0 to 8.0 #95289
Comments
Tagging subscribers to this area: @dotnet/area-system-numerics Issue DetailsDescriptionMostly I'm hitting
which is odd as there's 1) there's no a priori way of knowing the mask value, so There's also at least one similar case trivially addressed at MSIL gen time by loop unrolling (depending on data marshalling requirements for serialization, actual use cases may have 50+
ConfigurationVisual Studio 17.8.1. Regression?The DataThis class may be a conveniently simple example for reference. AnalysisOne possibility is If it is a correct warning, it's unclear to me how SIMD intrinsic code for x64 processors can be modified in .NET 8.0 to clear it. Googling gives me plenty of hits on SIMD
|
The warning is because you're using
It is not. APIs like There is an alternative API, The expected usage of this is: Vector128<float> mask = Avx.CompareEqual(arg1, arg2));
Avx.BlendVariable(arg3, arg4, mask); Doing this should give you a measurable performance increase and behave more as expected.
You should not suppress these. They are warning you of what is functionally "incorrect" code and where you should be using some other API or alternative mechanism in its place. There are some places where the JIT will try to recognize and optimize particular patterns when the user doesn't pass in a constant, but these are not guaranteed and may not always be supported by other runtimes. There are likewise many places the JIT doesn't try to handle today and where the developer doing the "right thing" themselves is the best option. |
This issue has been marked |
There are notable approved, but not yet implemented, analyzers to help direct users away from problematic patterns and towards more correct alternatives: #82488 and #82486 Cases like users calling Until the analyzer can be implemented and supported, I'm happy to help direct how different |
D'oh, thanks Tanner! That all sounds great; sorry I missed the extra Do you have a suggestion for the
This clears the CA1857 but, since it feels like trying to second guess JIT despite the disclaimers above, I'm unsure if it's a better bet codegen-wise than
|
For cases like In general, using the "cross platform" equivalent API (like |
From a general "write portable code once" standpoint, I agree. Most of the SIMD code I work with goes like Another reason I have calls like I've had a chance in the past couple days to flip several SIMD-bearing repos to .NET 8.0 and am not seeing interestingly different variations from what's already been discussed. I think this could therefore be closed since it looks like all the extract options are awkward somewhere. |
Notably
It's a fairly esoteric scenario that largely only impacts startup performance. It's typical that regular R2R performance is fine and any hot functions will be rejitted such that you get stable throughput within the first few seconds regardless. You have a similar option,
Many hardware instructions can be fairly awkward to use or come with limitations. That's why we expose the xplat APIs to help cover core patterns where the important thing is to do that as fast as possible and not with very specific instructions. |
Mmm, when I've looked at telling crossgen2 not to worry about legacy CPUs there've been meaningful runtime effects. Even with most of the runtime in compute kernels explicitly coded to Thanks for mentioning What does work great is your System.Runtime.Intrinsics implementation—thank you for all the time saved in coding C#-C++/CLI-C++ stacks—and then doing our own CPU dispatch. There's some overhead there, sure, but it's been lower cost than trying to coax this aspect of .NET builds into happiness. |
Description
Mostly I'm hitting
which is odd as there's 1) there's no a priori way of knowing the mask value, so
mask
cannot be declaredconst
, 2) mask cannot be marked[ConstExpected]
, and 3)mask
is a value type consumed directly byblendps
and similar instructions, so there doesn't appear to be an optimization for the compiler to take in response to the mask being constant.There's also at least one similar case trivially addressed at MSIL gen time by loop unrolling (depending on data marshalling requirements for serialization, actual use cases may have 50+
Extract()
s, meaning manual loop unrolling is unrealistic, IMO ).Configuration
Visual Studio 17.8.1.
Regression?
The
Blend()
disassembly I've been getting looks fine, so I'm inclined to say yes. Perhaps there are corner cases where poor codegen can occur, though.Data
This class may be a conveniently simple example for reference.
Analysis
One possibility is
[ConstExpected]
was added to response toconst int imm8
in the intrinsics' C signatures. From what I know, this doesn't appear to be a correct mapping between C/C++ notions of const, C# notions of const, the implications ofConstExpectedAttribute
, and how (E)VEX SIMD instructions access ymm (or zmm or mask) registers. So possibly the CA1857s here artifacts of the tool used for #80192.If it is a correct warning, it's unclear to me how SIMD intrinsic code for x64 processors can be modified in .NET 8.0 to clear it. Googling gives me plenty of hits on SIMD
[ConstExpected]
being added as an 8.0 feature but nothing on code migration paths. Class-level CA1857 suppressions are therefore tempting. I'd prefer a more graceful approach if one's available, though.The text was updated successfully, but these errors were encountered: