Math.Atan2和FPATAN

问题描述 投票:7回答:1

我正在用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不/不能执行这种明显的优化吗?

c# .net x86 trigonometry
1个回答
5
投票

您可以从this answer中追查原因,它显示了抖动如何映射这些数学函数。

将带您进入clr / src / classlibnative / float / comfloat.cpp,ComDouble :: Atan2()函数。解释原因:

   // the intrinsic for Atan2 does not produce Nan for Atan2(+-inf,+-inf)
   if (IS_DBL_INFINITY(x) && IS_DBL_INFINITY(y)) {
       return(x / y);      // create a NaN
   }
   return (double) atan2(x, y);

因此,这是解决不符合CLI的FPU行为的解决方法。

© www.soinside.com 2019 - 2024. All rights reserved.