-
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
Don't re-instrument methods which don't need that #84772
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch, @kunalspathak Issue DetailsCloses #84517 static void Main()
{
for (int i = 0; i < 100; i++)
{
Test1();
var _ = Test2;
Thread.Sleep(16);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static int Test1()
{
int sum = 0;
for (int i = 0; i < 1000; i++)
sum += i;
return sum;
}
static int Test2 { get; set; } Was:
Now:
|
/azp run runtime-coreclr pgo, runtime-coreclr libraries-pgo |
Azure Pipelines successfully started running 2 pipeline(s). |
PTAL @AndyAyersMS thoughts on the approach? |
Seems like you perhaps should keep this "don't need to instrument" bit on the NativeCodeVersion instead of the MethodDesc? |
I agree with Andy. |
Thanks! Looks like it has plenty of space
considering that PS: changed it to:
|
/azp run runtime-coreclr pgo, runtime-coreclr libraries-pgo |
Azure Pipelines successfully started running 2 pipeline(s). |
Moved to NativeCodeVersion, failures are #84798 |
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, but I wonder...
Can we see the same effect with simple R2R methods? That is, would we do R2R -> Tier1 + instr -> Tier1 even if Tier1+instr did not add any probes because the method was trivial?
I wonder if a simpler way of detecting these cases is for the jit interface to track if a schema was created during jitting (that is, if allocPgoInstrumentationBySchema
ever got called during this jit attempt).
- If at Tier0 with allow eager instrumentation flag, and the JIT created a schema, bypass future instrumentation requests (JIT decided to do eager instrumentation)
- If at Tier1 BBINSTR and the JIT did not create a schema when the VM requested one, then the current code is Tier1 quality, and so will not benefit from more rejitting.
This would consolidate the logic on the VM side.
Ah, interesting idea, I'll try |
957fe5a
to
78efc23
Compare
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.
This version LGTM
libraries-pgo was green last I looked, so maybe fire off that or some other pgo stress leg? |
/azp run runtime-coreclr pgo, runtime-coreclr libraries-pgo, runtime-coreclr pgostress |
Azure Pipelines successfully started running 3 pipeline(s). |
@jkotas do vm changes look good to you to merge? |
@kouvel Could you please take a look? |
} | ||
|
||
// Leave a note that this method is properly instrumented | ||
currentVersion.SetInstrumented(); |
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.
NativeCodeVersion
is a simple wrapper around either a MethodDesc
or a NativeCodeVersionNode
, and is typically passed by value. The default native code version doesn't have a node and just wraps a MethodDesc
. So, it's not a good candidate for persistent storage of this type of info. This change to the code version would just modify the local copy and would not be persisted anywhere.
AFAIK there isn't a clear place currently where such info could be stored. CallCountingInfo
may be a candidate, for instance see CallCountingManager::DisableCallCounting()
and CallCountingInfo::CreateWithCallCountingDisabled()
, which are used to indicate that a code version should not be tiered. However, currently it's not set up to store extra info aside from call counting, for example CallCountingManager::SetCodeEntryPoint()
does something different if the CallCountingInfo
already exists as opposed to when it's being created. It may be possible to enable precreating a CallCountingInfo
for a code version by introducing a new CallCountingInfo::Stage
something like NotStarted
to indicate that call counting has not started, and to modify SetCodeEntryPoint()
to do something similar to before in that case. If the CallCountingInfo
already exists, it could be used as persistent storage, as the CallCountingManager
has a hash table mapping a code version to a CallCountingInfo
.
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.
Maybe it's better to rollback to occupying a spare bit in MethodDesc
m_flag2 then? This change is a sort of an optimization, not correctness. The problem with CallCountingStubs that they're created assyncronlsy like you pointed out
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.
The info appears to be specific to a code version rather than a method desc, so I'm not sure the method desc would be an appropriate place for it
private: | ||
|
||
enum NativeCodeVersionFlag : UINT16 |
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 suggest using an enum class
to avoid polluting the parent namespace, though this may need to be moved based on my other comment.
CodeVersionManager* pCodeVersionManager = m_pMethodBeingCompiled->GetCodeVersionManager(); | ||
CodeVersionManager::LockHolder codeVersioningLockHolder; | ||
ILCodeVersion ilVersion = pCodeVersionManager->GetActiveILCodeVersion(m_pMethodBeingCompiled); | ||
NativeCodeVersion currentVersion = ilVersion.GetActiveNativeCodeVersion(m_pMethodBeingCompiled); |
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.
The active code version may have changed meanwhile, so it may not represent the current code version being jitted. Could use something like this instead:
runtime/src/coreclr/vm/jitinterface.cpp
Line 6681 in 7b662a7
PrepareCodeConfig *config = GetThread()->GetCurrentPrepareCodeConfig(); |
Along with config->GetCodeVersion()
.
Draft Pull Request was automatically closed for 30 days of inactivity. Please let us know if you'd like to reopen it. |
Closes #84517
Was:
Now:
What happened:
get_Test2()
is not promoted to Tier0-Instrumented since Tier0 realized it's too simple for that so it's promoted to Tier1 (it's also not needed here but that is a different issue)Test1()
promoted itself to Tier0-Instrumented due to loops so it also now tells vm it doesn't need to be promoted to Tier0-Instrumented again (and discard OSR versions)