-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Slightly improve profiled casts #96731
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
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsThis PR:
Example: for (int i = 0; i < 200; i++)
{
Test(new Program());
Thread.Sleep(10);
}
static void Test(object o)
{
if (o is Program)
Console.WriteLine();
} ; Assembly listing for method Program:Test(System.Object) (Tier1)
G_M3485_IG01:
sub rsp, 40
;; size=4 bbWeight=1 PerfScore 0.25
G_M3485_IG02:
mov rax, rcx
test rax, rax
je SHORT G_M3485_IG04
;; size=8 bbWeight=1 PerfScore 1.50
G_M3485_IG03:
mov rdx, 0xD1FFAB1E ; Program
cmp qword ptr [rax], rdx
jne SHORT G_M3485_IG07
;; size=15 bbWeight=0.50 PerfScore 2.12
G_M3485_IG04:
test rax, rax
je SHORT G_M3485_IG05
call [System.Console:WriteLine()]
;; size=11 bbWeight=1 PerfScore 4.25
G_M3485_IG05:
nop
;; size=1 bbWeight=1 PerfScore 0.25
G_M3485_IG06:
add rsp, 40
ret
;; size=5 bbWeight=1 PerfScore 1.25
G_M3485_IG07:
mov rdx, rcx
mov rcx, 0xD1FFAB1E ; Program
call CORINFO_HELP_ISINSTANCEOFCLASS
jmp SHORT G_M3485_IG04
;; size=20 bbWeight=0 PerfScore 0.00
; Total bytes of code 64
|
@AndyAyersMS @dotnet/jit-contrib PTAL,
Small diffs due to more blocks marked as cold (due to profile) https://dev.azure.com/dnceng-public/public/_build/results?buildId=522520&view=ms.vss-build-web.run-extensions-tab (I suspect the real diffs could be bigger but that needs new collections) |
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.
Was this based on any regression? Lack of improvement? Or just something you realized made more sense?
In our class profile probes we ignore cases with null objects. I wonder if for casting we shouldn't ignore them, then you would know how often the null case might come up...? We could make this change generally but would need to think through the repercussions on consumers; some of them are likely not expecting to see a null result. For example: HCIMPL2(void, JIT_ClassProfile32, Object *obj, ICorJitInfo::HandleHistogram32* classProfile)
{
FCALL_CONTRACT;
FC_GC_POLL_NOT_NEEDED();
OBJECTREF objRef = ObjectToOBJECTREF(obj);
VALIDATEOBJECTREF(objRef);
size_t sampleIndex;
if (!CheckSample(&classProfile->Count, &sampleIndex) || objRef == NULL)
{
return;
}
MethodTable* pMT = objRef->GetMethodTable(); could be HCIMPL2(void, JIT_ClassProfile32, Object *obj, ICorJitInfo::HandleHistogram32* classProfile)
{
FCALL_CONTRACT;
FC_GC_POLL_NOT_NEEDED();
OBJECTREF objRef = ObjectToOBJECTREF(obj);
VALIDATEOBJECTREF(objRef);
size_t sampleIndex;
if (!CheckSample(&classProfile->Count, &sampleIndex))
{
return;
}
MethodTable* pMT = (objRef == NULL) ? NULL : objRef->GetMethodTable(); |
The part that changes weights definitely improves code densitiy and my microbenchmark. The changed threshold is purely speculative at this point. Although, there are
That's a very good point - I was considering it too, I was just not sure how to trace null properly. I assume the empy table is basically all nulls, right? So how do I tell the difference between a table that is just almost empty (because we only had 1 hit) vs a very hot table that is half null because values are nulls? Should I pre-init it with some magic value? Or it's not a bid deal to handle cold tables like hot ones? |
I'll experiment with nulls separately |
This PR:
Changes the likelihood threshold, it used to be
(UINT32)JitConfig.JitGuardedDevirtualizationChainLikelihood()
(makes no sense) which is75
and I changed it to40
because any cast with two likelily classes won't be handed otherwise (50/50). It's based on our threshold for GDV for calls which is20-30
, I just made it a bit more conservative since the benefit is smaller.Adds ability to save weights (likelihoods) inside a Qmark.
Example:
CORINFO_HELP_ISINSTANCEOFCLASS
is now a cold block (because our profile is monomorphic)