Skip to content

Conversation

@VSadov
Copy link
Member

@VSadov VSadov commented Mar 23, 2023

Re: #82744 (comment)
Fixes: #83111

Turns out NativeAOT already emits optimized GC descs. That just follows from the implementation that builds complete pointer maps and scans them for series. Array-of-all-pointer-structs cases were not considered on some code paths though.

In the most general case CoreClr builds GC descs by appending GC descs of constituent parts - the base class and struct fields. It does use the compact "all-pointers" form, but only for object arrays.
With this change we detect most of the cases of all-pointers instances and use a compact 1-serie GC desc.

This is not a 100% match of the optimal GC descs produced by NativeAOT.
For example NativeAOT will naturally coalesce adjacent all-pointers structs in the middle of an instance into one contiguous GC serie. NativeAOT has more time and more motivation for this (the number of statically required method tables could be a lot higher than what is actually used at run time and using more compact forms reduces size).
For the JIT scenario, handling "all-pointers" seems good enough and also what we can do cheaply and allocation-free at JIT time.

@ghost ghost assigned VSadov Mar 23, 2023
@VSadov VSadov requested review from davidwrighton and jkotas March 23, 2023 00:29
@jkotas
Copy link
Member

jkotas commented Mar 23, 2023

Lots of failures...

@VSadov
Copy link
Member Author

VSadov commented Mar 23, 2023

I realized that couple of changes are not necessary and reverted them right before staging the PR.
Possibly reverted too much :)

@VSadov
Copy link
Member Author

VSadov commented Mar 23, 2023

I've tried collecting crude statistics of how often the optimizations make a difference in Libraries testcases.

It varies a lot, but in general I see:

  • 1-3% non-array cases get optimized to fewer series than otherwise.
    Object-derived classes are optimal anyways and complex types often contain ints and the like which break "all-pointers" case.
    Overall the hit rate does not seem like a lot, but it may be helping the array case and may become more interesting as inline arrays become more common as we may see more "all-pointers" structs.

  • ~10% array cases
    This is on top of about 50% of arrays that are object arrays and are already optimized. I think here the optimization is definitely worth it.


// ====================== GCDescOpt ==========================================================

[Fact]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test will need to be disabled for Mono

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@VSadov
Copy link
Member Author

VSadov commented Mar 23, 2023

Thanks!!

@VSadov VSadov merged commit 6246ce3 into dotnet:main Mar 23, 2023
@VSadov VSadov deleted the allPtrs branch March 23, 2023 19:27
@ghost ghost locked as resolved and limited conversation to collaborators Apr 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize GC series for cases where all instance fields could be represented as a single serie

2 participants