Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Enable trimming TLS arrays in ArrayPool.Shared#56316

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
stephentoub merged 3 commits intodotnet:mainfromstephentoub:trimmingtls
Jul 31, 2021

Conversation

@stephentoub
Copy link
Member

Today arrays stored inArrayPool<T>.Shared's per-core buckets have trimming applied, but arrays stored in the per-thread buckets are only trimmed when there's high memory pressure. This change enables all buffers to be trimmed (eventually). Every time our gen2 callback runs, it ensures any non-timestamped buffers have a timestamp, and also ensures that any timestamped buffers are still timely... if any aren't, they're eligible for trimming. The timestamp is reset for TLS arrays when they're stored, and for per-core buckets when they transition from empty to non-empty; the latter is just a tweak on the current behavior, which incurs the cost of Environment.TickCount upon that transition, whereas now we only pay it as part of the trimming pass.

Contributes to#52098
cc:@jkotas,@Maoni0

antonfirsov reacted with thumbs up emoji
@ghost
Copy link

Tagging subscribers to this area:@GrabYourPitchforks, @dotnet/area-system-buffers
See info inarea-owners.md if you want to be subscribed.

Issue Details

Today arrays stored inArrayPool<T>.Shared's per-core buckets have trimming applied, but arrays stored in the per-thread buckets are only trimmed when there's high memory pressure. This change enables all buffers to be trimmed (eventually). Every time our gen2 callback runs, it ensures any non-timestamped buffers have a timestamp, and also ensures that any timestamped buffers are still timely... if any aren't, they're eligible for trimming. The timestamp is reset for TLS arrays when they're stored, and for per-core buckets when they transition from empty to non-empty; the latter is just a tweak on the current behavior, which incurs the cost of Environment.TickCount upon that transition, whereas now we only pay it as part of the trimming pass.

Contributes to#52098
cc:@jkotas,@Maoni0

Author:stephentoub
Assignees:-
Labels:

area-System.Buffers

Milestone:-

Copy link
Member

@jkotasjkotas left a comment

Choose a reason for hiding this comment

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

Thank you!

@vargaz
Copy link
Contributor

The failures are caused by a linker problem. Here is the original finally clause in ::Trim ():

     finally    {      IL_009a:  ldloc.s    V_5      IL_009c:  brfalse.s  IL_00a5      IL_009e:  ldloc.s    V_5      IL_00a0:  callvirt   instance void System.IDisposable::Dispose()      IL_00a5:  endfinally    }  // end handler

and here is the linked version:

    finally    {      IL_0091:  ldloc.s    V_5      IL_0093:  brfalse.s  IL_009c      IL_0095:  ldloc.s    V_5      IL_0097:  callvirt   instance void System.IDisposable::Dispose()      IL_009c:  endfinally      IL_009d:  ldloc.1      IL_009e:  ldc.i4.1      IL_009f:  bne.un.s   IL_00aa      IL_00a1:  ldc.i4     0x3a98    }  // end handler

@stephentoub
Copy link
MemberAuthor

The failures are caused by a linker problem

cc:@sbomer,@vitek-karas

@danmoseley
Copy link
Member

@antonfirsov

@stephentoub
Copy link
MemberAuthor

@steveisok, how can we unblock this PR?

@danmoseley
Copy link
Member

@stephentoub failures in runtime-staging configurations do not block merge. Although, I thought they should not show up as red for that reason.

@steveisok
Copy link
Member

steveisok commentedJul 30, 2021
edited
Loading

@stephentoub failures in runtime-staging configurations do not block merge. Although, I thought they should not show up as red for that reason.

That's true for test failures only. If you have a build failure, then it'll show up red.

@danmoseley
Copy link
Member

(I mean, they don't block merge if the failures aren't clearly related. If this change breaks them more, we probably don't want to merge it.)

@danmoseley
Copy link
Member

That makes sense.

@stephentoub
Copy link
MemberAuthor

I mean, they don't block merge if the failures aren't clearly related. If this change breaks them more, we probably don't want to merge it.

Right. The problem is that the correct C# code and generated IL introduced by this PR is then getting mutilated by the linker and causing the AOT compiler to seg fault. As a temporary workaround to unblock this PR, I'd be happy to tweak the C# code to avoid whatever pattern is tripping up the linker, if someone can suggest what that pattern is. But it seems to me there's both a bug in the linker (dotnet/linker#2181) and a bug in the AOT compiler (seg faulting in response to bad IL) to be fixed here.

@jkotas
Copy link
Member

if someone can suggest what that pattern is.

My guess is that ifdefing the logging specific paths in Trim method for Mono is going to workaround the linker bug:

#if !MONO // Workaround for http://github.com/...     if (log.IsEnabled())     {     ....     }     else#endif
stephentoub reacted with thumbs up emoji

@stephentoub
Copy link
MemberAuthor

Ok, thanks, I'll give that a go.

Today arrays stored in `ArrayPool<T>.Shared`'s per-core buckets have trimming applied, but arrays stored in the per-thread buckets are only trimmed when there's high memory pressure.  This change enables all buffers to be trimmed (eventually).  Every time our gen2 callback runs, it ensures any non-timestamped buffers have a timestamp, and also ensures that any timestamped buffers are still timely... if any aren't, they're eligible for trimming.  The timestamp is reset for TLS arrays when they're stored, and for per-core buckets when they transition from empty to non-empty; the latter is just a tweak on the current behavior, which incurs the cost of Environment.TickCount upon that transition, whereas now we only pay it as part of the trimming pass.
@stephentoubstephentoub merged commit7d9a08c intodotnet:mainJul 31, 2021
@stephentoubstephentoub deleted the trimmingtls branchJuly 31, 2021 16:13
@DrewScoggins
Copy link
Member

We are seeing some wins in the ArrayPool perf tests as a result of this change.

image

@stephentoub
Copy link
MemberAuthor

Thanks,@DrewScoggins. It wasn't the initial intention of the PR, but I'm glad it had this affect (I expect from removing the TickCount check every time we transitioned from 0 to 1 array stored in the per-core stack). Do you see any movement here that might counteract what you reported in#56555?

@DrewScoggins
Copy link
Member

Yes, we saw some of it come back, but not all.

image

Sign up for freeto subscribe to this conversation on GitHub. Already have an account?Sign in.

Reviewers

@jkotasjkotasjkotas approved these changes

+1 more reviewer

@antonfirsovantonfirsovantonfirsov left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

6.0.0

Development

Successfully merging this pull request may close these issues.

7 participants

@stephentoub@vargaz@danmoseley@steveisok@jkotas@DrewScoggins@antonfirsov

[8]ページ先頭

©2009-2025 Movatter.jp