我正在用 C# 编写一些数学代码,强制它在发布时为 x86 编译,优化,我正在查看 windbg 中的反汇编。它通常非常好,经常写出比我能写的更好的汇编(并不是说我非常擅长汇编,但是你去吧)。
但是,我注意到这个功能:
static void TemporaryWork()
{
double x = 4;
double y = 3;
double z = Math.Atan2(x, y);
}
正在生产这个反汇编:
001f0078 55 push ebp
001f0079 8bec mov ebp,esp
001f007b dd05a0001f00 fld qword ptr ds:[1F00A0h]
001f0081 83ec08 sub esp,8
001f0084 dd1c24 fstp qword ptr [esp]
001f0087 dd05a8001f00 fld qword ptr ds:[1F00A8h]
001f008d 83ec08 sub esp,8
001f0090 dd1c24 fstp qword ptr [esp]
001f0093 e86e9ba66f call clr!GetHashFromBlob+0x94e09 (6fc59c06) (System.Math.Atan2(Double, Double), mdToken: 06000de7)
001f0098 ddd8 fstp st(0)
001f009a 5d pop ebp
001f009b c3 ret
即使您不是 x86 专家,您也会注意到其中有些奇怪的地方:调用了 System.Math.Atan2。就像在函数调用中一样。
但实际上有一个 x86 操作码可以做到这一点:FPATAN
当有实际的汇编指令来执行操作时,为什么 JITer 会调用函数?我认为 System.Math 基本上是本机汇编指令的包装器。那里的大多数操作都有直接汇编操作码。但显然情况并非如此?
有没有人知道为什么 JITer 不能/不能执行这个相当明显的优化?