-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Implement System.Array functions used by MD arrays as intrinsics #60816
Implement System.Array functions used by MD arrays as intrinsics #60816
Conversation
Tagging subscribers to this area: @JulieLeeMSFT Issue DetailsSpecifically, implement:
get_Rank is implemented for both SZ and MD arrays, and replaces the result The others are implemented as intrinsics for MD arrays only, when given Thus, exceptional cases fall back to the IL code which throws an exception Example x64 codegen for 2-D GetLength(1):
GetLowerBound(1):
GetUpperBound(1):
|
The recently added
This is no surprise, as the loops being measured look like:
|
var td = HandleToObject(cls) as ArrayType; | ||
Debug.Assert(td != null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like crossgen2 was too restrictive: the VM code passes returns zero if it's not a MD or SZ array.
@dotnet/jit-contrib PTAL |
/azp run runtime-coreclr outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
Good point. The JIT inlines and optimizes the function call anyway for the general case. Will remove the intrinsic handling. |
/azp run runtime-coreclr outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
Good to see improvements in this area, I think I saw a couple of public benchmarks where .NET was in a very bad place because author decided to benchmark multi-dimension arrays 🙂 Any spmi diffs? just to make sure this area is well covered (tests) |
There are a few tests that cover MD arrays, such as my newly added MDGeneralArray. And I've been using a little test program as well. However, no SPMI diffs, but that's because the new NamedIntrinsic and library attributions changes the JIT-EE interface. There are jit-diff diffs on the tests that use these functions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes LGTM.
One somewhat tangential question.
// See the comments at the definition of CORINFO_Array for a description of how arrays are laid out in memory. | ||
// | ||
// static | ||
unsigned Compiler::eeGetArrayDataOffset() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realize the code below is pre-existing but does this work right when cross-targeting (say 64 bit hosted 32 bit targeted)?
Seems like it must, somehow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, OFFSETOF__CORINFO_Array__data
is ifdef'ed on TARGET_64BIT
but everything else is target/bitness-independent, and we build compile-time target-bitness-specific JITs, so seems like it's all set up to work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I missed that this is not offsetof(CORINFO_Array, i1Elems)
or similar, but a separately defined thing.
Specifically, implement: - get_Rank - GetLength - GetLowerBound - GetUpperBound get_Rank is implemented for both SZ and MD arrays, and replaces the result with a constant. It falls back to IL for generic System.Array types. The others are implemented as intrinsics for MD arrays only, when given a constant dimension argument that is less than the array rank (that is, in range). Thus, exceptional cases fall back to the IL code which throws an exception as appropriate. Example x64 codegen for 2-D `int[,]` array (instead of call or inlined call): GetLength(1): ``` mov r9d, dword ptr [rcx+20] ``` GetLowerBound(1): ``` mov r9d, dword ptr [rcx+28] ``` GetUpperBound(1): ``` mov r9d, dword ptr [rcx+28] mov r10d, dword ptr [rcx+20] lea r10d, [r9+r10-1] ```
e83af0b
to
2ace1b8
Compare
Specifically, implement:
These are implemented as intrinsics for MD arrays only, when given
a constant dimension argument that is less than the array rank (that is,
in range).
Thus, exceptional cases fall back to the IL code which throws an exception
as appropriate.
Example x64 codegen for 2-D
int[,]
array (instead of call or inlined call):GetLength(1):
GetLowerBound(1):
GetUpperBound(1):