You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The x86 JIT on which RyuJIT did some unrolling. As far as I can tell the code is still there but it doesn't run - see optUnrollLoops in optimizer.cpp. It doesn't run because optCanCloneLoops always returns true, probably loop cloning (new to RyuJIT) somehow interferes with the old loop unrolling code. That said, the unrolling done by the x86 JIT isn't great:
for(inti=0;i<3;i++)sum+=i;
generates
inc eax
inc eax
inc eax
Good loop unrolling isn't trivial and I doubt that the existing unrolling code can be significantly improved.
That said, the unrolling done by the x86 JIT isn't great:
for (int i = 0; i < 3; i++)
sum += i;
generates
inc eax
inc eax
inc eax
Forgive the dumb question (I'm trying to learn about the JIT), but what would you expect it to generate? Something like this (or whatever the correct assembly is for adding 3):
@mattwarren Yes, add eax, 3 is expected for the code that I posted. Though the real version includes a sum = 0 so it's really mov eax, 3 as in the LegacyJIT-X64 version posted above by @AndreyAkinshin.
And in case that you wonder how come 3 increment instructions were produced: the loop got unrolled as: sum += 0; sum += 1; sum += 2;. The first addition was eliminated because it's useless and the last addition was emitted as inc eax, inc eax because this sequence is one byte shorter than add eax, 2.
@AndreyAkinshin Your LegacyJIT-x86 starts with the wrong instruction in al,dx. It's really a push ebp but you see in al,dx because the VS disassembly window has a bug. Not that it would matter.
(and COMPlus_TieredCompilation=0), which allows unrolling for any counted loop (not just with SIMD element count bounds), there are 331 tests that unroll a loop, but many unroll in a duplicate function, such as System.SpanHelpers:LastIndexOf().
Activity
mikedn commentedon May 13, 2015
The x86 JIT on which RyuJIT did some unrolling. As far as I can tell the code is still there but it doesn't run - see
optUnrollLoopsin optimizer.cpp. It doesn't run becauseoptCanCloneLoopsalways returns true, probably loop cloning (new to RyuJIT) somehow interferes with the old loop unrolling code. That said, the unrolling done by the x86 JIT isn't great:generates
Good loop unrolling isn't trivial and I doubt that the existing unrolling code can be significantly improved.
mattwarren commentedon May 13, 2015
@mikedn
Forgive the dumb question (I'm trying to learn about the JIT), but what would you expect it to generate? Something like this (or whatever the correct assembly is for adding 3):
Or is that too much to expect?
AndreyAkinshin commentedon May 13, 2015
@mikedn, @mattwarren
Here are the asm listings of the method
for different JIT versions:
LegacyJIT-x86:
LegacyJIT-x64:
RyuJIT-x64 RC:
mikedn commentedon May 13, 2015
@mattwarren Yes,
add eax, 3is expected for the code that I posted. Though the real version includes asum = 0so it's reallymov eax, 3as in the LegacyJIT-X64 version posted above by @AndreyAkinshin.And in case that you wonder how come 3 increment instructions were produced: the loop got unrolled as:
sum += 0; sum += 1; sum += 2;. The first addition was eliminated because it's useless and the last addition was emitted asinc eax, inc eaxbecause this sequence is one byte shorter thanadd eax, 2.@AndreyAkinshin Your LegacyJIT-x86 starts with the wrong instruction
in al,dx. It's really apush ebpbut you seein al,dxbecause the VS disassembly window has a bug. Not that it would matter.AndreyAkinshin commentedon May 13, 2015
@mikedn, Thanks, it explains a lot!
BruceForstall commentedon May 13, 2015
/cc @briansull @schellap
hez2010 commentedon May 29, 2020
An interesting sample:
LegacyJIT:
RyuJIT:
Anyway, hoping that loop unrolling and auto-vectorize in RyuJIT can be implemented ASAP :)
BruceForstall commentedon Oct 30, 2020
Only a few tests in the tree cause loop unrolling to kick in, since the current heuristic requires a constant loop over a SIMD vector length:
with
(and
COMPlus_TieredCompilation=0), which allows unrolling for any counted loop (not just with SIMD element count bounds), there are 331 tests that unroll a loop, but many unroll in a duplicate function, such asSystem.SpanHelpers:LastIndexOf().