এখানে একটি বাস্তব বিশ্বের উদাহরণ: পুরানো সংকলকগুলিতে স্থির পয়েন্টের গুণগুলি।
এগুলি কেবল ভাসমান বিন্দু ছাড়াই ডিভাইসে কার্যকর হয় না, যখন তারা ভবিষ্যদ্বাণীযোগ্য ত্রুটি সহ 32 বিট নির্ভুলতা দেয় (যথাযথ ক্ষতি হওয়ার পূর্বাভাস দেওয়া আরও কঠিন) তবে তারা যখন জ্বলন্ত জ্বলজ্বল করে তখনই তারা জ্বলজ্বল করে। অর্থাত্ কাছাকাছি-ইউনিফর্ম সম্পর্কিত আপেক্ষিক যথার্থতা ( ) এর পরিবর্তে পুরো ব্যাপ্তির উপর অভিন্ন পরম স্পষ্টতাfloat
আধুনিক সংকলকগণ এই স্থির-দৃষ্টান্তের উদাহরণটি সুন্দরভাবে অনুকূল করেছেন, সুতরাং আরও আধুনিক উদাহরণগুলির জন্য এখনও সংকলক-নির্দিষ্ট কোডের প্রয়োজন, দেখুন need
সি-তে একটি পূর্ণ-গুণক অপারেটর নেই (এন-বিট ইনপুট থেকে 2N-বিট ফলাফল)। সি তে প্রকাশ করার স্বাভাবিক উপায় হ'ল ইনপুটগুলি আরও বিস্তৃত প্রকারে ফেলে দেওয়া এবং আশা করি যে সংকলকটি বুঝতে পারে যে ইনপুটগুলির উপরের বিটগুলি আকর্ষণীয় নয়:
// on a 32-bit machine, int can hold 32-bit fixed-point integers.
int inline FixedPointMul (int a, int b)
{
long long a_long = a; // cast to 64 bit.
long long product = a_long * b; // perform multiplication
return (int) (product >> 16); // shift by the fixed point bias
}
এই কোডটির সমস্যাটি হ'ল আমরা এমন কিছু করি যা সি-ভাষায় সরাসরি প্রকাশ করা যায় না। আমরা দুটি 32 বিট সংখ্যাকে গুণ করতে এবং একটি 64 বিটের ফলাফল পেতে চাই যার মধ্যবর্তী 32 বিটকে আমরা ফিরিয়ে আনব। তবে সি তে এই গুণটির কোন অস্তিত্ব নেই। আপনি যা করতে পারেন তা হ'ল ইন্টিজারগুলি 64 বিটে প্রচার করা এবং একটি 64 * 64 = 64 গুণ করা।
x86 (এবং এআরএম, এমআইপিএস এবং অন্যান্য) তবে একক নির্দেশায় গুণ করতে পারে। কিছু সংকলক এই সত্যটিকে উপেক্ষা করে কোড তৈরি করে যা একটি রানটাইম লাইব্রেরি ফাংশনকে গুণিত করতে ডাকে। ১ by-এর শিফটটি প্রায়শই একটি লাইব্রেরি রুটিন দ্বারাও করা হয় (এছাড়াও x86 এ জাতীয় শিফট করতে পারে)
সুতরাং আমরা এক বা দুটি গ্রন্থাগার কল রেখেছি কেবল একটি বহুগুণ জন্য for এর মারাত্মক পরিণতি রয়েছে। শিফটটি কেবল ধীর নয়, রেজিস্টারগুলি অবশ্যই ফাংশন কলগুলিতে সংরক্ষণ করতে হবে এবং এটি ইনলাইনিং এবং কোড-তালিকাভুক্তিতেও সহায়তা করে না।
আপনি যদি একই কোডটি (ইনলাইন) এসেম্বলারে পুনরায় লিখেন তবে আপনি একটি গতিময় গতি বৃদ্ধি করতে পারেন।
এগুলি ছাড়াও: এএসএম ব্যবহার করা সমস্যা সমাধানের সর্বোত্তম উপায় নয়। বেশিরভাগ সংকলক আপনাকে সিগুলিতে প্রকাশ করতে না পারলে অভ্যন্তরীণ আকারে কিছু সংযোজক নির্দেশাবলী ব্যবহারের অনুমতি দেয় VS.NET2008 সংকলক উদাহরণস্বরূপ 32 * 32 = 64 বিট মুলকে __emul হিসাবে এবং thell_rsift হিসাবে bit৪ বিট শিফটটি প্রকাশ করে।
আন্তঃব্যবহার ব্যবহার করে আপনি ফাংশনটি এমনভাবে পুনরায় লিখতে পারেন যাতে সি-সংকলকটির কী হচ্ছে তা বোঝার সুযোগ রয়েছে। এটি কোডটিকে ইনলাইনড করতে, নিবন্ধীকৃত বরাদ্দ করতে, সাধারণ স্বেচ্ছাসেবী বিলোপ এবং ধ্রুবক প্রচারও করা যায়। আপনি সেইভাবে হাতে লিখিত এসেম্বলারের কোডের মাধ্যমে একটি বিশাল পারফরম্যান্সের উন্নতি পাবেন ।
রেফারেন্সের জন্য: ভিএস.এনইটি সংকলকের স্থির-পয়েন্ট মুলের শেষ ফলাফলটি হ'ল:
int inline FixedPointMul (int a, int b)
{
return (int) __ll_rshift(__emul(a,b),16);
}
ফিক্সড পয়েন্ট বিভাজনের পারফরম্যান্স পার্থক্য আরও বড়। আমার বেশ কয়েকটি এসএম-লাইন লিখে ডিভিশন ভারী ফিক্সড পয়েন্ট কোডের জন্য দশমিক 10 গুণমান পর্যন্ত উন্নতি হয়েছিল।
ভিজ্যুয়াল সি ++ 2013 ব্যবহার করে উভয় উপায়ে একই সমাবেশ কোড দেয়।
2007 থেকে gcc4.1 এছাড়াও খাঁটি সি সংস্করণটিকে সুন্দরভাবে অনুকূল করে। (গডবোল্ট সংকলক এক্সপ্লোরার জিসিসির কোনও পূর্ববর্তী সংস্করণ ইনস্টল করেনি, তবে সম্ভবত সম্ভবত পুরানো জিসিসি সংস্করণগুলিও অন্তর্নিহিত ছাড়াই এটি করতে পারে))
গডবোল্ট সংকলক এক্সপ্লোরার এক্স x86 (32-বিট) এবং এআরএমের জন্য উত্স + asm দেখুন । (দুর্ভাগ্যক্রমে এটি সাধারণ খাঁটি সি সংস্করণ থেকে খারাপ কোড তৈরি করার মতো পুরানো কোনও সংকলক নেই))
আধুনিক CPU- র জিনিষ সি জন্য অপারেটরদের নেই কি করতে পারেন এ সব মত, popcnt
বা বিট-স্ক্যানের প্রথম অথবা শেষ সেট বিট এটি । (পসিক্সের একটি ffs()
ফাংশন রয়েছে তবে এর শব্দার্থকগুলি x86 bsf
/ এর সাথে মেলে না bsr
। Https://en.wikedia.org/wiki/Find_first_set দেখুন )।
কিছু সংকলক কখনও কখনও এমন একটি লুপ সনাক্ত করতে পারে যা একটি পূর্ণসংখ্যায় সেট বিটের সংখ্যা গণনা করে এটি একটি popcnt
নির্দেশিকায় সংকলন করে (সংকলনের সময় সক্ষম করা থাকে) তবে এটি __builtin_popcnt
GNU C, বা x86 এ ব্যবহার করা আরও নির্ভরযোগ্য যদি আপনি কেবলমাত্র এসএসই 4.2 দিয়ে হার্ডওয়্যারকে লক্ষ্য করে: _mm_popcnt_u32
থেকে<immintrin.h>
।
অথবা সি ++ এ একটি std::bitset<32>
ব্যবহার করুন .count()
। (এটি এমন একটি ক্ষেত্রে যেখানে ভাষাটি স্ট্যান্ডার্ড লাইব্রেরির মাধ্যমে পপকাউন্টের একটি অনুকূলিতকরণ বাস্তবায়ন বহন করার উপায় খুঁজে পেয়েছে, এমন একটি উপায়ে যা সর্বদা সঠিক কিছু সংকলন করে, এবং লক্ষ্যটি যা সমর্থন করে তাতে সুবিধা নিতে পারে)) আরও দেখুন https : //en.wikedia.org/wiki/ হ্যামিং_ওয়েট # ল্যাঙ্গুয়েজ_সুপোর্ট ।
তেমনি কিছু সি বাস্তবায়নের ntohl
ক্ষেত্রে bswap
(এন্ডিয়ান রূপান্তরকরণের জন্য x86 32-বিট বাইট স্যুপ) সংকলন করতে পারেন ।
অন্তর্নিহিত বা হস্ত লিখিত asm জন্য আর একটি বড় ক্ষেত্র হ'ল সিমডি নির্দেশাবলী সহ ম্যানুয়াল ভেক্টরাইজেশন। সংযোজকগুলি সরল লুপগুলির মতো খারাপ হয় না dst[i] += src[i] * 10.0;
তবে জিনিসগুলি যখন আরও জটিল হয় তখন প্রায়শই খারাপভাবে কাজ করে বা অটো-ভেক্টরাইজ করে না। উদাহরণস্বরূপ, সিমড ব্যবহার করে আটোয় কীভাবে বাস্তবায়ন করবেন এর মতো কিছু পাওয়ার সম্ভাবনা আপনার নেই ? স্কেলার কোড থেকে সংকলক দ্বারা স্বয়ংক্রিয়ভাবে উত্পাদিত।