Skip to content

[ConstraintSystem] Add a new stat to be used for expression type chec… #19930

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

Merged
merged 2 commits into from
Oct 19, 2018
Merged

[ConstraintSystem] Add a new stat to be used for expression type chec… #19930

merged 2 commits into from
Oct 19, 2018

Conversation

rudkx
Copy link
Contributor

@rudkx rudkx commented Oct 17, 2018

…ker performance testing.

This counts the number of leaf scopes we reach while solving the
constraint sytem, and is a much better measure of the growth of
unnecessary work than the total number of scopes opened.

There were two tests where I had a difficult time getting scale-test
to fit the curve even after adjusting some of the parameters, so I've
left those to use the old stat for now.

…ker performance testing.

This counts the number of leaf scopes we reach while solving the
constraint sytem, and is a much better measure of the growth of
unnecessary work than the total number of scopes opened.

There were two tests where I had a difficult time getting scale-test
to fit the curve even after adjusting some of the parameters, so I've
left those to use the old stat for now.
@rudkx rudkx requested review from xedin and graydon October 17, 2018 14:57
@rudkx
Copy link
Contributor Author

rudkx commented Oct 17, 2018

@swift-ci Please smoke test

@@ -1439,6 +1433,10 @@ class ConstraintSystem {

void incrementScopeCounter();

void numLeafScopes(unsigned adjustment);
void incrementLeafScopes(unsigned increment =1);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit - indentation after =

// not been split, so allow each additional component after the
// first to have a free leaf scope that doesn't count against the
// total for the system.
CS.decrementLeafScopes(Components.size() - 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

As far as I understand the behavior, we can only reach "leaf" scope when:

  1. None of the previous components failed but current did (and components which follow it up are not going to allocate scopes);
  2. Disjunction choice has been "attempted" without problems - choice constraint has been simplified, but then failed to attempt any type variables;
  3. Last successful type variable in the path has been bound (because all type variables attempted before it would create intermediate scopes).

So the question is - if we always decrement by the number of components here but not all of the components resulted in at least one recorded "leaf" scope (e.g. one failed so all the rest had to be aborted), wouldn't it mean that this counter would go negative and/or overflow?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We count something as a leaf scope any time it creates no new scopes. That could be because we found a successful solution or because a constraint failed. So we should always increment this at least once per component.

My hope here is that this counter will provide the same value whether we split a system or not. i.e., if we take a system and solve it without splitting it and hit 10 leafs, I would like to ensure that if we took the same system and split it into three we would also end up with a count of 10 leafs (rather than 10 plus two extra ones for the two successful endpoints in the two new components).

Does that make sense and if so are there still any concerns?

I can look at adding asserts to ensure we never roll over or go negative.

Copy link
Contributor

Choose a reason for hiding this comment

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

Take a look at the ComponentStep::take, we don’t allocate scopes if previous components failed...

Copy link
Contributor

@graydon graydon left a comment

Choose a reason for hiding this comment

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

In general: very happy to see new instrumentation for a more-accurate count of work the typechecker does! In specific though, a few concerns:

  • If you want this on in the field (or graphed/tracked in CI perf testing) you need to use the UnifiedStatsReporter's AlwaysOnFrontendCounters fields (defined by entries in include/swift/Basic/Statistics.def, not llvm:Statistic; the latter is compiled-out in release builds. It's also atomic ops and therefore a fair bit more expensive when on.

  • The stats-profiling machinery will get confused if counters decrement along the way. They should be monotonically increasing if at all possible (I mean it's not the end of the world if you can't, but it'll make any profiles misleading and wrong).

  • As @xedin mentions I'm a little concerned that the increments and decrements won't balance out, and would be cautious about being 100% sure they do if you're going to leave it as non-monotonic.

@rudkx
Copy link
Contributor Author

rudkx commented Oct 18, 2018

@graydon I'll take another look at the always-on counters. It wasn't clear to me if these got reported out when doing scale-test, so I did the lazy-programmer approach of copying what was already happening for the total scope count.

@rudkx
Copy link
Contributor Author

rudkx commented Oct 18, 2018

@graydon Oh yes, and on decreasing counts - are these being sampled within a constraint system?

If not, then I don't think there should be a problem here since they should always be increasing from system to system.

@graydon
Copy link
Contributor

graydon commented Oct 18, 2018

@rudkx All stats get sampled on every construction/destruction of any FrontendStatsTracer.

In the process, remove the old incrementScopeCounter SWIFT_FUNC_STAT.
@rudkx
Copy link
Contributor Author

rudkx commented Oct 18, 2018

@xedin @graydon Okay, I reworked this to only use the always-on stats and updated the tests to use that stat instead. The counter only increments, and it accurately counts the number of leaf scopes we hit, but the counter will vary with the number of connected components we find which is unfortunate but not the end of the world.

@rudkx
Copy link
Contributor Author

rudkx commented Oct 18, 2018

@swift-ci Please smoke test

@rudkx
Copy link
Contributor Author

rudkx commented Oct 18, 2018

@swift-ci please smoke test Linux platform

Copy link
Contributor

@xedin xedin left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Contributor

@graydon graydon left a comment

Choose a reason for hiding this comment

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

Looks good, thanks!

@rudkx rudkx merged commit b892e6b into swiftlang:master Oct 19, 2018
@rudkx rudkx deleted the extend-operator-designated-type branch October 19, 2018 01:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants