MethodImplOptions.InternalCall
তার মানে হল যে পদ্ধতিটি আসলে সিএলআর-তে সিএলআর-তে লিখিত হয়েছে। কেবলমাত্র ইন-টাইম সংকলক অভ্যন্তরীণভাবে প্রয়োগ করা পদ্ধতিগুলির সাথে একটি টেবিলের পরামর্শ নেয় এবং কলটি সরাসরি সি ++ ফাংশনে সংকলন করে।
কোডটি দেখার জন্য সিএলআর এর উত্স কোডের প্রয়োজন। আপনি এটি এসএসসিএলআই 20 বিতরণ থেকে পেতে পারেন । এটি .NET 2.0 টাইম ফ্রেমের চারপাশে লেখা হয়েছিল, আমি নিম্ন-স্তরের বাস্তবায়ন খুঁজে পেয়েছি, Math.Pow()
সিএলআরের পরবর্তী সংস্করণগুলির জন্য এখনও বেশিরভাগ ক্ষেত্রে সঠিক হতে চাই ।
চেহারা টেবিলটি 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 এ নিয়ে যায়। আমি আপনাকে কোডটি ছাড়ব, কেবল নিজের জন্য দেখুন। এটি মূলত কোণার কেসগুলি পরীক্ষা করে, তারপরে সিআরটি'র সংস্করণকে কল করে pow()
।
কেবলমাত্র অন্য বাস্তবায়ন বিশদটি যা আকর্ষণীয় তা হ'ল টেবিলে FCIntrinsic ম্যাক্রো। এটি একটি ইঙ্গিত যা ঘিটারটি অভ্যন্তরীণ হিসাবে ফাংশনটি প্রয়োগ করতে পারে। অন্য কথায়, ফ্লোটিং পয়েন্ট মেশিন কোড নির্দেশের সাথে ফাংশন কলটির বিকল্প দিন। যার ক্ষেত্রে এটি নয় Pow()
, এর জন্য কোনও এফপিইউ নির্দেশনা নেই। তবে অবশ্যই অন্যান্য সাধারণ অপারেশনগুলির জন্য। উল্লেখযোগ্য যে, এই C # ফ্লোটিং পয়েন্ট গণিত যথেষ্ট দ্রুত সি একই কোড চেয়ে করা যায় ++ পরীক্ষা এই উত্তর কারণে জন্য।
যাইহোক, সিআরটি-এর উত্স কোডটি যদি আপনার কাছে ভিজ্যুয়াল স্টুডিও ভিসি / সিআরটি / এসসিআর ডিরেক্টরিটির সম্পূর্ণ সংস্করণ থাকে তবে উপলব্ধ। pow()
যদিও আপনি প্রাচীরটিকে আঘাত করবেন , মাইক্রোসফ্ট ইন্টেল থেকে এই কোডটি কিনেছিল। ইন্টেল ইঞ্জিনিয়ারদের চেয়ে আরও ভাল কাজ করা অসম্ভব। যদিও আমার উচ্চ-বিদ্যালয়ের বইয়ের পরিচয় দ্বিগুণ দ্রুত ছিল যখন আমি এটি চেষ্টা করেছি:
public static double FasterPow(double x, double y) {
return Math.Exp(y * Math.Log(x));
}
তবে সত্যিকারের বিকল্প নয় কারণ এটি 3 ভাসমান পয়েন্ট অপারেশনগুলি থেকে ত্রুটি সংগ্রহ করে এবং পাওয়ার () এর যে অদ্ভুত ডোমেন সমস্যা রয়েছে তা মোকাবেলা করে না। 0 ^ 0 এবং -অনফিনিটি যেকোন শক্তি বাড়িয়েছে।
InternalCall
কোনওextern
সংশোধক ( পুরোপুরি বিরোধী বলে মনে করেন) দিয়ে পুরো সম্পর্কে বিভ্রান্ত হন তবে দয়া করে আমি এই প্রশ্নটি সম্পর্কে পোস্ট করা প্রশ্নটি (এবং ফলস্বরূপ উত্তরগুলি) দেখুন ।