why won't JIT inline this?

F

Fuzzy

I have written a custom replacement for library function
Math.Pow(double x, double y) for the specific condition of y being
integer and >=0. It is twice as fast as Math.Pow(), but I cannot get
the compiler to inline compile it. I've tried many different
approaches, but nothing seems to work. I am debugging in native
mode, and I do see property get's inlined as I would expect.

Any ideas?

C# code, IL code, and the optimized disassembly follow:

C# code:
public static double IntPower(double x, int y)
{
double r=1;
while (y>0)
{
r*=x;
y--;
}
return r;
}


ILDASM:
..method public hidebysig static float64 IntPower(float64 x,
int32 y) cil managed
{
// Code size 27 (0x1b)
.maxstack 2
.locals init (float64 V_0)
IL_0000: ldc.r8 1.
IL_0009: stloc.0
IL_000a: br.s IL_0015
IL_000c: ldloc.0
IL_000d: ldarg.0
IL_000e: mul
IL_000f: stloc.0
IL_0010: ldarg.1
IL_0011: ldc.i4.1
IL_0012: sub
IL_0013: starg.s y
IL_0015: ldarg.1
IL_0016: ldc.i4.0
IL_0017: bgt.s IL_000c
IL_0019: ldloc.0
IL_001a: ret
} // end of method EMath::IntPower



disassembly:
set and call IntPower() function:
02FD04E5 push 40080000h
02FD04EA push 0
02FD04EC mov ecx,2
02FD04F1 call dword ptr ds:[3E6854h] ...


IntPower function:
02FD07B0 fld1
02FD07B2 cmp ecx,0
02FD07B5 jle 02FD07C3
02FD07B7 fld qword ptr [esp+4]
02FD07BB fmulp st(1),st
02FD07BD dec ecx
02FD07BE cmp ecx,0
02FD07C1 jg 02FD07B7
02FD07C3 ret 8
 
J

Jon Skeet [C# MVP]

Fuzzy said:
I have written a custom replacement for library function
Math.Pow(double x, double y) for the specific condition of y being
integer and >=0. It is twice as fast as Math.Pow(), but I cannot get
the compiler to inline compile it. I've tried many different
approaches, but nothing seems to work. I am debugging in native
mode, and I do see property get's inlined as I would expect.

Any ideas?

I believe the JIT compiler doesn't inline anything involving loops.
 
W

Willy Denoyette [MVP]

Fuzzy said:
I have written a custom replacement for library function
Math.Pow(double x, double y) for the specific condition of y being
integer and >=0. It is twice as fast as Math.Pow(), but I cannot get
the compiler to inline compile it. I've tried many different
approaches, but nothing seems to work. I am debugging in native
mode, and I do see property get's inlined as I would expect.

Any ideas?

The JITter will not inline complex flow controls, complex here means
anything else then if/then/else (in your case while).

Willy.
 
F

Fuzzy

Jon Skeet said:
I believe the JIT compiler doesn't inline anything involving loops.

That's really disappointing. This loop is so small that it could
easily be inlined. I'll manually inline it to see how the performance
changes; and also see at what exponent value the calculation time
overwhelms the function call overhead.

Thanks for the response.
 
F

Fuzzy

Willy Denoyette said:
The JITter will not inline complex flow controls, complex here means
anything else then if/then/else (in your case while).

Willy.

SO, you think a 'goto' would be inlined? Something like:

IntPower(double x, int y)
{ r=1;
start:
if (y>1)
{ r*=x;
y--;
goto start;
}
return r;
 
J

Jerry III

I think it was said clearly, any flow control other than if/then/else won't
be inlined. Goto is not one of if/then/else.

Jerry
 
W

Willy Denoyette [MVP]

No, as I said only If/then/else control constructs, nothing that would
involve conditional looping.
Note that in your sample the call overhead is very small compared to the
execution time of the loop, especially when y is large.
Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top