MethodImplOptions.InternalCall
นั่นหมายความว่าวิธีการดังกล่าวถูกนำไปใช้จริงใน CLR ซึ่งเขียนใน C ++ คอมไพเลอร์ทันเวลาให้คำปรึกษาตารางด้วยวิธีการที่ดำเนินการภายในและรวบรวมการเรียกไปยังฟังก์ชัน C ++ โดยตรง
การดูรหัสต้องใช้ซอร์สโค้ดสำหรับ CLR คุณจะได้รับจากการจัดจำหน่าย SSCLI20 มันถูกเขียนรอบกรอบเวลา. NET 2.0 ฉันพบการใช้งานระดับต่ำเช่นMath.Pow()
ว่ายังคงมีความถูกต้องส่วนใหญ่สำหรับ CLR รุ่นที่ใหม่กว่า
ตารางการค้นหาอยู่ใน clr / src / vm / ecall.cpp ส่วนที่เกี่ยวข้องกับMath.Pow()
มีลักษณะดังนี้:
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 ฉันจะขอรหัสให้คุณดูด้วยตัวคุณเอง มันเป็นพื้นการตรวจสอบสำหรับกรณีมุมแล้วเรียกรุ่น CRT pow()
ของ
รายละเอียดการใช้งานอื่น ๆ ที่น่าสนใจคือแมโคร FCIntrinsic ในตาราง นั่นเป็นคำใบ้ที่กระวนกระวายใจอาจใช้ฟังก์ชั่นเป็นที่แท้จริง กล่าวอีกนัยหนึ่งแทนการเรียกใช้ฟังก์ชันด้วยคำสั่งรหัสเครื่องจุดลอย ซึ่งไม่ใช่ในกรณีที่Pow()
ไม่มีคำสั่ง FPU สำหรับมัน แต่แน่นอนสำหรับการดำเนินงานที่เรียบง่ายอื่น ๆ สิ่งที่น่าสังเกตคือสิ่งนี้สามารถสร้างเลขทศนิยมในภาษา C # ได้เร็วกว่ารหัสเดียวกันใน C ++ ตรวจสอบคำตอบนี้ด้วยเหตุผลว่าทำไม
อย่างไรก็ตามซอร์สโค้ดสำหรับ CRT ก็มีให้เช่นกันหากคุณมีไดเรกทอรี Visual Studio vc / crt / src เวอร์ชันเต็ม คุณจะชนกำแพงเมื่อpow()
ไมโครซอฟท์ซื้อรหัสนั้นจาก Intel ทำงานได้ดีกว่าวิศวกรของ Intel ไม่น่าเป็นไปได้ แม้ว่าตัวตนของหนังสือมัธยมของฉันจะเร็วเป็นสองเท่าเมื่อฉันลองทำ:
public static double FasterPow(double x, double y) {
return Math.Exp(y * Math.Log(x));
}
แต่ไม่ใช่สิ่งทดแทนที่แท้จริงเพราะมันสะสมข้อผิดพลาดจากการดำเนินการจุดลอยตัว 3 แห่งและไม่จัดการกับปัญหาโดเมนแปลก ๆ ที่ Pow () มี เช่น 0 ^ 0 และ - อินฟินิตี้ยกระดับพลังใด ๆ
InternalCall
ด้วยextern
ตัวปรับแต่ง (เนื่องจากดูเหมือนจะขัดแย้งกัน) โปรดดูคำถาม (และคำตอบที่เกิดขึ้น)ที่ฉันโพสต์เกี่ยวกับสิ่งเดียวกันนี้มาก