C#でいくつかの数学コードを書いていますが、それはリリースで最適化されたx86用にコンパイルする必要があり、私はwindbgで逆アセンブリを見ています。それは通常かなり良いです、しばしば私ができるよりも優れたアセンブリを書いています(私はすべてアセンブリでうまくいくわけではありませんが、そこに行く)。Math.Atan2とFPATAN
しかし、私はこの機能気づいた:
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がこの明白な最適化を実行できない/できない理由に関する情報をお持ちの人はいませんか?
私がGoogleのバグをfpatan'とすると、いくつかのプロセッサモデルでいくつかの結果が得られるので、 'Math.Atan2'がこれらのバグを回避して動作し、' Math.Atan'に置き換えられました。私は本当に確信していませんが、おそらくそれは探す方向になる可能性がありますか?良い質問。 – Silvermind
"JITerがなぜこの明白な最適化を実行できないのか/実行できないのかについての情報は誰にもありますか?"私は問題のJITについては言いませんが、複数のプラットフォームで 'atan2' FPATAN命令を呼び出すことは明白な*悲観化*となります.FPATANは、関数呼び出しのオーバーヘッドを含めても、優れたソフトウェア実装よりもはるかに低速です(150-300サイクル対50-100サイクル、 –