SORU
15 Ocak 2012, Pazar


Nasıl Matematik.() Pow uygulanmaktadır .NET Çerçeve?

Bir hesaplama için etkili bir yaklaşım arıyordumb(say = 2 ve b = 50). Bir şeyleri Başlat, Math.Pow() İşlev uygulaması bir göz atmaya karar verdim. Ama .NET Reflector tüm bulduğum bu

[MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical]
public static extern double Pow(double x, double y);

Ne kaynakları Math.Pow() fonksiyon çağırdığımda içinde neler olup bittiğini olarak görüyorum neyin?

CEVAP
15 Ocak 2012, Pazar


MethodImplOptions.InternalCall

Bu yöntem aslında CLR, C ile yazılmış uygulanır anlamına gelir . Just-in-time derleyici DAHİLİ olarak uygulanan yöntemler ile bir tablo danışır ve C işlevi çağrısı doğrudan derler.

Koda bir göz sahip, kaynak CLR için bir kod gerektirir. SSCLI20 distribution seni affedebilir. Etrafında yazılmıştır .NET 2.0 zaman çerçevesi, alt düzey uygulamaları, Math.Pow() gibi CLR sonraki sürümler için hala büyük ölçüde doğru olduğunun farkına vardım.

Arama tablosu clr/src/vm/ecall.cpp yer almaktadır. Math.Pow() alakalı bölümüne bu gibi görünüyor:

FCFuncStart(gMathFuncs)
    FCIntrinsic("Sin", COMDouble::Sin, CORINFO_INTRINSIC_Sin)
    FCIntrinsic("Cos", COMDouble::Cos, CORINFO_INTRINSIC_Cos)
    FCIntrinsic("Sqrt", COMDouble::Sqrt, CORINFO_INTRINSIC_Sqrt)
    FCIntrinsic("Round", COMDouble::Round, CORINFO_INTRINSIC_Round)
    FCIntrinsicSig("Abs", &gsig_SM_Flt_RetFlt, COMDouble::AbsFlt, CORINFO_INTRINSIC_Abs)
    FCIntrinsicSig("Abs", &gsig_SM_Dbl_RetDbl, COMDouble::AbsDbl, CORINFO_INTRINSIC_Abs)
    FCFuncElement("Exp", COMDouble::Exp)
    FCFuncElement("Pow", COMDouble::Pow)
    // etc..
FCFuncEnd()

"COMDouble" clr/src/classlibnative/float/comfloat.cpp alır arıyorum. Kod yedek, sadece kendiniz için bir göz atayım. Temel olarak köşe durumlarda denetler, pow() CRT versiyonu çağırır.

İlginç olan sadece diğer uygulama detay tabloda FCİntrinsic makro. Bu değişimi bir iç işlevi uygulamak olabilecek bir ipucu. Başka bir deyişle, işlev kayan nokta makine kodu Talimat ile arama yerine. Pow(), DEĞERLERİ talimat yok için durum böyle değil. Ama kesinlikle diğer basit işlemleri için. Bu C kayan nokta matematik yapabilir önemli# C aynı kodu daha önemli ölçüde daha hızlı , bu nedenle this answer neden kontrol edin.

Bu arada, CRT için kaynak kodunu Visual Studio vc/crt/src dizinin tam sürümü de mevcuttur. Microsoft, Intel, kod satın almış olsa pow() duvara çarpacaksın. Intel mühendisleri daha iyi bir iş yapmak mümkün değildir. Lise defterimi kimliğini ben denedim: iki kat daha hızlı olmasına rağmen

public static double FasterPow(double x, double y) {
    return Math.Exp(y * Math.Log(x));
}

Ama gerçek yerine 3 kayan nokta işlemleri hata birikir ve Pow o garip etki alanı sorunları ile anlaşma yok çünkü). 0^0 gibi ve -Sonsuz güç için kaldırdı.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • PaulGBelliveau

    PaulGBellive

    5 Mart 2009
  • Richard Laxa

    Richard Laxa

    30 AĞUSTOS 2012
  • The Dubstep FX

    The Dubstep

    5 Mart 2011