c# Math.Sqrt 实现 [英] c# Math.Sqrt Implementation

查看:30
本文介绍了c# Math.Sqrt 实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近一直在使用 System.Math,前几天我想知道,Microsoft 将如何在库中实现 Sqrt 方法.于是我突然打开了我最好的伙伴Reflector,尝试在库中对方法进行Disassemble,结果显示:

I've been using System.Math quite a lot lately and the other day I was wondering, how Microsoft would have implemented the Sqrt method in the library. So I popped open my best mate Reflector and tried to Disassemble the method in the library, but it showed:

[MethodImpl(MethodImplOptions.InternalCall),ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static extern double Sqrt(double d);

那一天,我第一次意识到我的孩子是多么依赖这个框架,吃饭.

That day for the first time ever, I realized how dependent my kids are on the framework, to eat.

开个玩笑,但我想知道 MS 会使用哪种算法来实现此方法,或者换句话说,如果您没有库支持,您将如何在 C# 中编写自己的 Math.Sqrt 实现.

Jokes apart, but i was wondering what sort of algorithm MS would have used to implement this method or in other words how would you write your own implementation of Math.Sqrt in C# if you had no library support.

推荐答案

您通过 Reflector 或具有 MethodImplOptions.InternalCall 属性的 Reference Source 找到的任何方法实际上都是在 CLR 中的 C++ 中实现的.您可以从 SSCLI20 发行版中获取这些源代码.相关文件是 clr/src/vm/ecall.cpp,它包含一个带有函数指针的方法名称表,JIT 编译器使用该表将调用地址直接嵌入到生成的机器代码中.相关的表格部分是

Any of the methods you find back with Reflector or the Reference Source that have the MethodImplOptions.InternalCall attribute are actually implemented in C++ inside the CLR. You can get the source code for these from the SSCLI20 distribution. The relevant file is clr/src/vm/ecall.cpp, it contains a table of method names with function pointers, used by the JIT compiler to directly embed the call address into the generated machine code. The relevant table section is

FCIntrinsic("Cos", COMDouble::Cos, CORINFO_INTRINSIC_Cos)
FCIntrinsic("Sqrt", COMDouble::Sqrt, CORINFO_INTRINSIC_Sqrt)
FCIntrinsic("Round", COMDouble::Round, CORINFO_INTRINSIC_Round)
...

这会将你带到 clr/src/classlibnative/float/comfloat.cpp

Which takes you to clr/src/classlibnative/float/comfloat.cpp

FCIMPL1_V(double, COMDouble::Sqrt, double d)
    WRAPPER_CONTRACT;
    STATIC_CONTRACT_SO_TOLERANT;

    return (double) sqrt(d);
FCIMPLEND

它只是调用 CRT 函数.但这不是 x86 抖动中发生的情况,请注意表声明中的内在".你不会发现在 SSLI20 版本的抖动中,它是一个不受专利约束的简单的.然而,运输确实把它变成了内在的:

It just calls the CRT function. But that's not what happens in the x86 jitter, note the 'intrinsic' in the table declaration. You won't find that in the SSLI20 version of the jitter, it is a simple one unencumbered by patents. The shipping one however does turn it into an intrinsic:

double d = 2.0;
Console.WriteLine(Math.Sqrt(d));

翻译成

00000008  fld         dword ptr ds:[0072156Ch] 
0000000e  fsqrt 
..etc

换句话说,Math.Sqrt() 转换为单个浮点机器代码指令.查看this answer了解如何轻松击败本机代码的详细信息.

In other words, Math.Sqrt() translates to a single floating point machine code instruction. Check this answer for details on how that beats native code handily.

这篇关于c# Math.Sqrt 实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆